skip to content

What is Spring Authorization Server, and what role do RegisteredClient and RegisteredClientRepository play in it?

level: juniorimportance: must knowfreq 60%

answer

  1. Separate project, not Security core
  2. Issues access + id tokens
  3. RegisteredClient = one allowed app
  4. InMemory vs Jdbc repository
  5. findByClientId on each request

basics

~20 s

Spring Authorization Server is a standalone project that turns your app into an OAuth2/OIDC provider — it issues tokens. A RegisteredClient is one app allowed to request tokens; RegisteredClientRepository stores and looks up those clients.

solid answer

~40 s

Spring Authorization Server (a separate project from Spring Security, not part of the core framework) provides a compliant OAuth2 Authorization Server and OpenID Connect 1.0 Provider. It exposes endpoints like /oauth2/authorize, /oauth2/token and /oauth2/jwks and issues access tokens and OIDC id tokens. A RegisteredClient models a client application permitted to obtain tokens: its clientId/clientSecret, allowed authorization grant types (e.g. authorization_code, client_credentials), redirect URIs, and scopes. RegisteredClientRepository is the abstraction that saves and finds those clients — InMemoryRegisteredClientRepository for demos/tests, JdbcRegisteredClientRepository for persistence. On each token request the server loads the RegisteredClient by clientId to validate the request and decide what it may be issued.

code

java · 16 lines
java
RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
    .clientId("web-app")
    .clientSecret("{bcrypt}$2a$10$...")
    .clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
    .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
    .authorizationGrantType(AuthorizationGrantType.REFRESH_TOKEN)
    .redirectUri("https://app.example.com/login/oauth2/code/web-app")
    .scope(OidcScopes.OPENID)
    .scope("read")
    .clientSettings(ClientSettings.builder().requireProofKey(true).build())
    .build();

@Bean
RegisteredClientRepository registeredClientRepository() {
    return new InMemoryRegisteredClientRepository(client);
}

go deeper

for a junior

Know it issues tokens and that RegisteredClient = an app allowed to get tokens.

for a middle

Explain RegisteredClient fields (grant types, scopes, redirect URIs) and InMemory vs Jdbc repositories.

for a senior

Discuss client authentication methods, PKCE for public clients, and custom RegisteredClientRepository implementations.

for a principal

Weigh self-hosting an IdP vs delegating to Keycloak/Okta; persistence, multi-instance, and client-lifecycle management.

**What it is.** Spring Authorization Server is a dedicated Spring project (artifact `org.springframework.security:spring-security-oauth2-authorization-server`) that lets you host your own **OAuth2 Authorization Server** and **OpenID Connect (OIDC) 1.0 Provider**. It is *not* bundled in Spring Security core — you add it as a separate dependency. Its job is to **authenticate clients/users and issue tokens** that resource servers (APIs) then trust. **Vocabulary (assume nothing).** - *OAuth2*: a delegated-authorization protocol. A *client* application gets an **access token** to call protected APIs on a user's behalf. - *OIDC*: an identity layer on top of OAuth2 that additionally issues an **id token** (a JWT describing *who* the user is) and a discovery/userinfo mechanism. - *Client*: an application (e.g. a SPA, mobile app, or backend service) that requests tokens — distinct from the end user. - *Grant type*: the flow used to get a token (authorization_code, client_credentials, refresh_token, etc.). **RegisteredClient.** An immutable value object describing exactly one client that is allowed to talk to the server. Built via `RegisteredClient.withId(...)`. Key fields: - `clientId` / `clientSecret` — the client's credentials (secret typically encoded with a `PasswordEncoder`). - `clientAuthenticationMethod(s)` — how the client proves itself, e.g. `CLIENT_SECRET_BASIC`, `NONE` for public clients using PKCE. - `authorizationGrantType(s)` — `AUTHORIZATION_CODE`, `CLIENT_CREDENTIALS`, `REFRESH_TOKEN`, etc. - `redirectUri(s)` — allowed callback URLs (validated exactly on the authorization_code flow). - `scope(s)` — permissions the client may ask for; `OidcScopes.OPENID` is required to get an id token. - `clientSettings` / `tokenSettings` — e.g. require PKCE, require consent, token TTLs, token format. **RegisteredClientRepository.** The strategy interface the server uses to persist and retrieve clients. Two methods matter: `save(RegisteredClient)` and `findByClientId(String)` / `findById(String)`. Built-in implementations: - `InMemoryRegisteredClientRepository` — a fixed in-memory list; great for tests and demos, lost on restart. - `JdbcRegisteredClientRepository` — persists to a relational database using the schema shipped with the project; the production choice. You can also implement it yourself (e.g. to load clients from your own tables or a config service). **How it fits at runtime.** When a token request arrives, the server extracts the `clientId`, calls `findByClientId`, and uses the returned `RegisteredClient` to validate the request (is this grant allowed? is the redirect URI registered? are the scopes permitted?) and to shape the issued tokens. **Gotchas.** - The server is a separate deployable/config; don't confuse it with `spring-security-oauth2-client` (which makes your app a *client*) or `spring-security-oauth2-resource-server` (which makes your app validate tokens). - `InMemoryRegisteredClientRepository` state is lost on restart and not shared across instances — never use it in production. - A missing `openid` scope means no id token is issued even though it's an OIDC-configured server. **When to use.** Choose Spring Authorization Server when you need to *own* your identity/token issuance (internal IdP, first-party SSO) instead of delegating to Okta/Auth0/Keycloak.

  • Which repository implementation would you use in production and why?
    JdbcRegisteredClientRepository, so clients survive restarts and are shared across all server instances via the database; InMemory is only for tests/demos.
  • How does the server know which app is calling?
    The client authenticates (e.g. clientId+secret via CLIENT_SECRET_BASIC, or PKCE for public clients); the server looks up the RegisteredClient by clientId to validate the request.

saying these in an interview costs you the question

  • Thinking Spring Authorization Server is part of Spring Security core rather than a separate project
  • Confusing it with oauth2-client (consumer) or resource-server (validator)
  • Believing InMemoryRegisteredClientRepository is fine for production

context