Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify configuring authorization server using HttpSecurity.with() #1725

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 66 additions & 54 deletions docs/modules/ROOT/pages/configuration-model.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@

`OAuth2AuthorizationServerConfiguration` uses xref:configuration-model.adoc#customizing-the-configuration[`OAuth2AuthorizationServerConfigurer`] to apply the default configuration and registers a `SecurityFilterChain` `@Bean` composed of all the infrastructure components supporting an OAuth2 authorization server.

[TIP]
`OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity)` is a convenience (`static`) utility method that applies the default OAuth2 security configuration to `HttpSecurity`.

The OAuth2 authorization server `SecurityFilterChain` `@Bean` is configured with the following default protocol endpoints:

* xref:protocol-endpoints.adoc#oauth2-authorization-endpoint[OAuth2 Authorization endpoint]
Expand Down Expand Up @@ -58,11 +55,14 @@ https://openid.net/specs/openid-connect-core-1_0.html[OpenID Connect 1.0] is dis
----
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);

http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Initialize `OidcConfigurer`

OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Initialize `OidcConfigurer`
);
return http.build();
}
----
Expand Down Expand Up @@ -105,28 +105,31 @@ Furthermore, it lets you customize the request processing logic for the protocol
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);

authorizationServerConfigurer
.registeredClientRepository(registeredClientRepository) <1>
.authorizationService(authorizationService) <2>
.authorizationConsentService(authorizationConsentService) <3>
.authorizationServerSettings(authorizationServerSettings) <4>
.tokenGenerator(tokenGenerator) <5>
.clientAuthentication(clientAuthentication -> { }) <6>
.authorizationEndpoint(authorizationEndpoint -> { }) <7>
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { }) <8>
.deviceVerificationEndpoint(deviceVerificationEndpoint -> { }) <9>
.tokenEndpoint(tokenEndpoint -> { }) <10>
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) <11>
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) <12>
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { }) <13>
.oidc(oidc -> oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint -> { }) <14>
.logoutEndpoint(logoutEndpoint -> { }) <15>
.userInfoEndpoint(userInfoEndpoint -> { }) <16>
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) <17>
OAuth2AuthorizationServerConfigurer.authorizationServer();

http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.registeredClientRepository(registeredClientRepository) <1>
.authorizationService(authorizationService) <2>
.authorizationConsentService(authorizationConsentService) <3>
.authorizationServerSettings(authorizationServerSettings) <4>
.tokenGenerator(tokenGenerator) <5>
.clientAuthentication(clientAuthentication -> { }) <6>
.authorizationEndpoint(authorizationEndpoint -> { }) <7>
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> { }) <8>
.deviceVerificationEndpoint(deviceVerificationEndpoint -> { }) <9>
.tokenEndpoint(tokenEndpoint -> { }) <10>
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint -> { }) <11>
.tokenRevocationEndpoint(tokenRevocationEndpoint -> { }) <12>
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint -> { }) <13>
.oidc(oidc -> oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint -> { }) <14>
.logoutEndpoint(logoutEndpoint -> { }) <15>
.userInfoEndpoint(userInfoEndpoint -> { }) <16>
.clientRegistrationEndpoint(clientRegistrationEndpoint -> { }) <17>
)
);

return http.build();
Expand Down Expand Up @@ -232,18 +235,21 @@ It defines extension points that let you customize the pre-processing, main proc
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);

authorizationServerConfigurer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationConverter(authenticationConverter) <1>
.authenticationConverters(authenticationConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.authenticationSuccessHandler(authenticationSuccessHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
OAuth2AuthorizationServerConfigurer.authorizationServer();

http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationConverter(authenticationConverter) <1>
.authenticationConverters(authenticationConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.authenticationSuccessHandler(authenticationSuccessHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
);

return http.build();
Expand Down Expand Up @@ -288,13 +294,16 @@ The following example shows how to configure `JwtClientAssertionAuthenticationPr
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();

authorizationServerConfigurer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationProviders(configureJwtClientAssertionValidator())
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationProviders(configureJwtClientAssertionValidator())
)
);

return http.build();
Expand Down Expand Up @@ -339,14 +348,17 @@ If you need to verify another attribute of the client `X509Certificate`, for exa
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();

authorizationServerConfigurer
.clientAuthentication(clientAuthentication ->
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationProviders(configureX509ClientCertificateVerifier())
);
.authenticationProviders(configureX509ClientCertificateVerifier())
)
);

return http.build();
}
Expand Down
58 changes: 33 additions & 25 deletions docs/modules/ROOT/pages/core-model-components.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@ Alternatively, you can configure the `RegisteredClientRepository` through the xr
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();

authorizationServerConfigurer
.registeredClientRepository(registeredClientRepository);

...
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.registeredClientRepository(registeredClientRepository)
)
...

return http.build();
}
Expand Down Expand Up @@ -218,13 +220,15 @@ Alternatively, you can configure the `OAuth2AuthorizationService` through the xr
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();

authorizationServerConfigurer
.authorizationService(authorizationService);

...
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationService(authorizationService)
)
...

return http.build();
}
Expand Down Expand Up @@ -290,13 +294,15 @@ Alternatively, you can configure the `OAuth2AuthorizationConsentService` through
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();

authorizationServerConfigurer
.authorizationConsentService(authorizationConsentService);

...
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationConsentService(authorizationConsentService)
)
...

return http.build();
}
Expand Down Expand Up @@ -401,13 +407,15 @@ Alternatively, you can configure the `OAuth2TokenGenerator` through the xref:con
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);

authorizationServerConfigurer
.tokenGenerator(tokenGenerator);

...
OAuth2AuthorizationServerConfigurer.authorizationServer();

http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenGenerator(tokenGenerator)
)
...

return http.build();
}
Expand Down
7 changes: 3 additions & 4 deletions docs/modules/ROOT/pages/guides/how-to-userinfo.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ TIP: Click on the "Expand folded text" icon in the code sample above to display
This configuration provides the following:

<1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
<2> Resource server support that allows User Info requests to be authenticated with access tokens.
<2> Enabling OpenID Connect 1.0 will autoconfigure resource server support that allows User Info requests to be authenticated with access tokens.
<3> An instance of `JwtDecoder` used to validate access tokens.

[[customize-user-info]]
Expand Down Expand Up @@ -87,9 +87,8 @@ This configuration maps claims from the access token (which is a JWT when using

<1> A Spring Security filter chain for the xref:{docs-dir}/protocol-endpoints.adoc[Protocol Endpoints].
<2> A user info mapper that maps claims in a domain-specific way.
<3> An example showing the configuration option for customizing the user info mapper.
<4> Resource server support that allows User Info requests to be authenticated with access tokens.
<5> An example showing how to apply the `OAuth2AuthorizationServerConfigurer` to the Spring Security configuration.
<3> Enabling OpenID Connect 1.0 will autoconfigure resource server support that allows User Info requests to be authenticated with access tokens.
<4> An example showing the configuration option for customizing the user info mapper.

The user info mapper is not limited to mapping claims from a JWT, but this is a simple example that demonstrates the customization option.
Similar to the xref:guides/how-to-userinfo.adoc#customize-id-token[example shown earlier] where we customize claims of the ID token, you can customize claims of the access token itself ahead of time, as in the following example:
Expand Down
Loading