⌂ Index
Kapitel 12 · Security

Spring Authorization Server und OAuth2/OIDC

Typ: FrameworkVersion 2 ausführlich

Spring Authorization Server stellt Bausteine für OAuth2- und OpenID-Connect-Authorization-Server bzw. Identity-Provider bereit.

Fachliche Einordnung

In Enterprise-Architekturen sollte nicht jede Anwendung eigene Login- und Tokenlogik bauen. Ein Authorization Server zentralisiert Clients, Grants, Token und Schlüssel.

Enterprise-Merksatz: Spring Authorization Server stellt Bausteine für OAuth2- und OpenID-Connect-Authorization-Server bzw. Identity-Provider bereit.

Technische Darstellung

Browser Client App Authorization Server JWK Access Token Resource Server
Kernkonzepte
  • RegisteredClient und ClientAuthentication.
  • Authorization Code Flow mit PKCE.
  • JWT, JWK Set und Key Rotation.
  • Scopes, Claims und Consent.
  • Abgrenzung zu Resource Servern und externen IdPs.
Wann einsetzen?
  • Du betreibst eigenen internen Identity Provider oder OAuth2 Server.
  • Du brauchst maschinenlesbare Token für Microservices.
  • Du willst bestehende Benutzerquelle mit OIDC verbinden.
Typische Fehler und Risiken
  • Eigenen Authorization Server bauen, obwohl ein Unternehmens-IdP existiert.
  • Refresh Tokens ohne Rotation und Lebensdauerregeln.
  • Claims mit Berechtigungen überladen.
Legacy- und Modernisierungssicht

Form Login, LDAP-Login oder proprietäre SSO-Lösungen werden schrittweise an OIDC/OAuth2 angebunden; APIs validieren danach Tokens als Resource Server.

Ausführliches Beispiel

Das Beispiel zeigt bewusst nicht nur Annotationen, sondern auch die Verantwortung der Schicht. In echten Projekten sollte der technische Spring-Code an Adapter- oder Konfigurationsrändern bleiben, während die Fachlogik testbar und möglichst frameworkarm bleibt.

@Configuration
class AuthorizationServerConfiguration {
    @Bean
    RegisteredClientRepository registeredClients(PasswordEncoder encoder) {
        RegisteredClient client = RegisteredClient.withId(UUID.randomUUID().toString())
            .clientId("order-portal")
            .clientSecret(encoder.encode("change-me"))
            .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
            .redirectUri("https://portal.example.com/login/oauth2/code/order")
            .scope("openid")
            .scope("order.write")
            .clientSettings(ClientSettings.builder().requireProofKey(true).build())
            .build();
        return new InMemoryRegisteredClientRepository(client);
    }
}
Checkliste für Reviews
  • Ist die Verantwortung des Bausteins klar: Framework steuert Lebenszyklus, Library wird gezielt benutzt?
  • Ist die Fachlogik außerhalb von Controller, Listener, Repository-Implementierung oder Konfiguration?
  • Sind Fehlerfälle, Timeouts, Security, Monitoring und Tests sichtbar modelliert?
  • Gibt es klare Grenzen zwischen DTO, Domäne, Persistence und Infrastruktur?