spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Add Spring Authorization Server support

Open sjohnr opened this issue 2 years ago • 1 comments

This PR introduces support for Spring Authorization Server. It includes:

  • New module spring-boot-starter-oauth2-authorization-server
  • Dependency management of org.springframework.security:spring-security-oauth2-authorization-server
  • Support in spring-boot-autoconfigure for org.springframework.security:spring-security-oauth2-authorization-server

Overview

The auto-configuration is designed to closely match the Getting Started guide in the reference manual. When spring-security-oauth2-authorization-server is detected on the classpath, the following components are optionally registered:

  • RegisteredClientRepository
  • AuthorizationServerSettings
  • SecurityFilterChain for protocol endpoints
  • SecurityFilterChain for user authentication with Form Login
  • com.nimbusds.jose.jwk.source.JWKSource<SecurityContext> with a generated RSA key-pair
  • JwtDecoder that uses the provided JWKSource

Because Spring Authorization Server is built on top of Spring Security, the order in which components are registered in collaboration with existing auto-configuration is important.

The main consideration is that UserDetailsServiceAutoConfiguration continue to be allowed to publish a UserDetailsService if necessary. However, a JwtDecoder must also be published afterwards. This is in-contrast with OAuth2ResourceServerAutoConfiguration which prevents a UserDetailsService from being published.

Configuration

The OAuth2AuthorizationServerProperties allow configuring RegisteredClients and AuthorizationServerSettings. Here is a typical client configuration with default settings:

spring:
  security:
    oauth2:
      authorizationserver:
        client-registration:
          messaging-client:
            client-id: messaging-client
            client-secret: "{noop}secret"
            client-authentication-methods:
              - client_secret_basic
            authorization-grant-types:
              - authorization_code
              - refresh_token
              - client_credentials
            redirect-uris:
              - http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc
              - http://127.0.0.1:8080/authorized
            scopes:
              - openid
              - profile
              - message.read
              - message.write
            client-settings:
              require-authorization-consent: true

Here is a full configuration example:

spring:
  security:
    oauth2:
      authorizationserver:
        settings:
          issuer: https://provider.com
          authorization-endpoint: /oauth2/authorize
          token-endpoint: /oauth2/token
          jwk-set-endpoint: /oauth2/jwks
          token-revocation-endpoint: /oauth2/revoke
          token-introspection-endpoint: /oauth2/introspect
          oidc-client-registration-endpoint: /connect/register
          oidc-user-info-endpoint: /userinfo
          additional-settings:
            custom-setting-1: value1
            custom-setting-2: value2
        client-registration:
          messaging-client:
            client-id: messaging-client
            client-secret: "{noop}secret"
            client-name: Messaging Client
            client-authentication-methods:
              - client_secret_basic
            authorization-grant-types:
              - authorization_code
              - refresh_token
              - client_credentials
            redirect-uris:
              - http://127.0.0.1:8080/login/oauth2/code/messaging-client-oidc
              - http://127.0.0.1:8080/authorized
            scopes:
              - openid
              - profile
              - message.read
              - message.write
            client-settings:
              require-proof-key: true
              require-authorization-consent: true
              jwk-set-url: http://127.0.0.1:8080/jwks
              token-endpoint-authentication-signing-algorithm: RS256
              additional-settings:
                custom-setting-1: value1
                custom-setting-2: value2
            token-settings:
              authorization-code-time-to-live: 5m
              access-token-time-to-live: 5m
              access-token-format: self-contained
              reuse-refresh-tokens: true
              refresh-token-time-to-live: 60m
              id-token-signature-algorithm: RS256
              additional-settings:
                custom-setting-1: value1
                custom-setting-2: value2

sjohnr avatar Jan 27 '23 23:01 sjohnr

Hi! It seems that the two auto-configuration classes OAuth2AuthorizationServerAutoConfiguration and OAuth2AuthorizationServerJwtAutoConfiguration are not configured in the org.springframework.boot.autoconfigure.AutoConfiguration.imports file and won't be loaded.

Is it possible to add a smoke test for the OAuth2 Authorization Server to catch such bugs and verify that it works correctly in a Boot application?

mhalbritter avatar Jan 31 '23 14:01 mhalbritter

@mhalbritter I've added the imports and a few basic smoke tests.

sjohnr avatar Feb 01 '23 23:02 sjohnr

Thank you!

mhalbritter avatar Feb 02 '23 08:02 mhalbritter

Hi @mhalbritter! Just checking to see if there is any additional feedback on this PR? I'm especially interested in feedback related to the config properties. If there's any changes needed, I will sync up with @jgrandja and make any needed updates ready for review.

sjohnr avatar Feb 07 '23 15:02 sjohnr

Hey, i'll bring it up on the next team meeting.

mhalbritter avatar Feb 07 '23 15:02 mhalbritter

Thanks for the PR @sjohnr. It's been merged into main along with this polish commit.

mbhave avatar Mar 22 '23 03:03 mbhave