What is Spring Authorization Server, and what role do RegisteredClient and RegisteredClientRepository play in it?
answer
- Separate project, not Security core
- Issues access + id tokens
- RegisteredClient = one allowed app
- InMemory vs Jdbc repository
- findByClientId on each request
basics
~20 sSpring 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 sSpring 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 linesRegisteredClient 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
Know it issues tokens and that RegisteredClient = an app allowed to get tokens.
Explain RegisteredClient fields (grant types, scopes, redirect URIs) and InMemory vs Jdbc repositories.
Discuss client authentication methods, PKCE for public clients, and custom RegisteredClientRepository implementations.
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