Loslegen
Javaneer
Zurück zur Stufe
Modul 12·Spring Authorization Server

Einen Authorization Server betreiben

Was Spring Authorization Server ist, ein minimales Setup und das Registrieren von Clients - der Unterschied zwischen dem Ausstellen von Tokens und dem bloßen Validieren.

15 Min. LesezeitExperte

Deutsche Übersetzung in Arbeit

Diese Lektion ist noch nicht ins Deutsche übersetzt und wird daher auf Englisch angezeigt. Der Rest der Seite ist vollständig lokalisiert.

Auf dieser Seite

Most Spring apps are resource servers or clients - they validate tokens or obtain them. Running an authorization server is the other side: the party that authenticates users and mints tokens in the first place. Spring Authorization Server is the official project for this. Understanding what it is (and when you actually need it) matters as much as the config.

Issuing vs. validating

Keep three responsibilities distinct - they're three different Spring modules:

  • Resource Server (spring-boot-starter-oauth2-resource-server) - validates incoming tokens and protects endpoints. This is what BookVault's API did with its HS256 shortcut.
  • Client (spring-boot-starter-oauth2-client) - obtains tokens by driving a login flow ("Sign in with Google").
  • Authorization Server (spring-security-oauth2-authorization-server) - issues tokens: authenticates the user, runs the grants, exposes the OAuth2/OIDC endpoints.

You only run an authorization server when you want to be the identity provider - your own login, your own tokens, multiple apps trusting one issuer. If you just want users to log in with Google or Okta, you're a client, not an authorization server.

A minimal server

Spring Authorization Server is a set of Spring Security filters you enable and configure. The core is a security filter chain that applies the OAuth2/OIDC endpoint defaults:

@Configuration
class AuthServerConfig {

    @Bean
    @Order(1)
    SecurityFilterChain authServer(HttpSecurity http) throws Exception {
        OAuth2AuthorizationServerConfigurer.authorizationServer()
            .oidc(Customizer.withDefaults());              // enable OpenID Connect
        return http
            .securityMatcher("/oauth2/**", "/.well-known/**", "/userinfo")
            .with(OAuth2AuthorizationServerConfigurer.authorizationServer(), c -> c.oidc(withDefaults()))
            .build();
    }

    @Bean
    @Order(2)
    SecurityFilterChain login(HttpSecurity http) throws Exception {
        return http.formLogin(withDefaults()).build();     // how users authenticate
    }
}

Turning it on exposes the standard endpoints automatically: /oauth2/authorize, /oauth2/token, /oauth2/jwks (the public keys), and the discovery document at /.well-known/openid-configuration that clients read to auto-configure.

Registering clients

An authorization server won't issue tokens to anyone - each app must be a registered client with an ID, (for confidential clients) a secret, its allowed redirect URIs, grant types, and scopes:

@Bean
RegisteredClientRepository clients(PasswordEncoder encoder) {
    RegisteredClient bookvaultSpa = RegisteredClient.withId(UUID.randomUUID().toString())
        .clientId("bookvault-web")
        .clientAuthenticationMethod(ClientAuthenticationMethod.NONE)     // public client (SPA)
        .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
        .redirectUri("https://app.bookvault.dev/callback")               // exact match required
        .scope(OidcScopes.OPENID).scope("catalog:read")
        .clientSettings(ClientSettings.builder().requireProofKey(true).build())  // PKCE
        .build();
    return new InMemoryRegisteredClientRepository(bookvaultSpa);
}

Every field is a security boundary: the exact redirect URI stops token theft via open redirects, the grant types limit what the client may do, and the scopes cap what its tokens can access.

In-memory is for demos only

InMemoryRegisteredClientRepository and in-memory keys reset on restart and don't work across replicas. In production, back the client repository with a database (JdbcRegisteredClientRepository) and load signing keys from a real keystore or secret manager - never generate them fresh on boot, or every restart invalidates every issued token.

A passport office, not a border guard

A resource server is a border guard: it inspects passports and waves people through, but it doesn't make passports. An authorization server is the passport office: it verifies your identity at the counter and issues the document itself. Registering a client is the office's list of recognized travel agencies - only an agency on the list, using the exact address on file, may request passports on travelers' behalf. Running the office is a bigger commitment than standing at the border, which is why you do it only when you truly need to be the issuer.

Server or client?

Two scenarios: (a) an internal company portal where employees log in once and access five internal Spring apps with the same account; (b) a hobby app where you just want visitors to sign in with their GitHub accounts. Which needs you to run a Spring Authorization Server, and which makes you an OAuth2 client - and why?

When do you actually need to run a Spring Authorization Server (rather than being a client or resource server)?

Key takeaways

  • Three distinct roles/modules: resource server validates tokens, client obtains them, authorization server issues them.
  • Run a Spring Authorization Server only when you want to be the identity provider - your own login and tokens trusted by multiple apps.
  • Enabling it exposes standard endpoints automatically: /oauth2/authorize, /oauth2/token, /oauth2/jwks, and the /.well-known discovery document.
  • Every app must be a registered client with an ID, optional secret, exact redirect URIs, grant types, and scopes - each field is a security boundary.
  • In-memory clients and boot-generated keys are demo-only; production needs a JDBC client repository and keys from a real keystore/secret manager.
War diese Lektion hilfreich?
Diese Seite auf GitHub bearbeiten