Simplify configuring authorization server using HttpSecurity.with()

Closes gh-1707
This commit is contained in:
Joe Grandja
2024-09-18 16:25:41 -04:00
parent 4d1e2d9711
commit 2c7975485f
25 changed files with 734 additions and 709 deletions

View File

@@ -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]
@@ -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();
}
----
@@ -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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
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>
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();
@@ -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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationConverter(authenticationConverter) <1>
.authenticationConverters(authenticationConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.authenticationSuccessHandler(authenticationSuccessHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
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();
@@ -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();
@@ -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();
}

View File

@@ -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();
}
@@ -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();
}
@@ -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();
}
@@ -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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.tokenGenerator(tokenGenerator);
...
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenGenerator(tokenGenerator)
)
...
return http.build();
}

View File

@@ -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]]
@@ -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:

View File

@@ -14,19 +14,22 @@ 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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authorizationRequestConverter(authorizationRequestConverter) <1>
.authorizationRequestConverters(authorizationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.authorizationResponseHandler(authorizationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.consentPage("/oauth2/v1/authorize") <7>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authorizationRequestConverter(authorizationRequestConverter) <1>
.authorizationRequestConverters(authorizationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.authorizationResponseHandler(authorizationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.consentPage("/oauth2/v1/authorize") <7>
)
);
return http.build();
@@ -74,13 +77,16 @@ The following example shows how to configure `OAuth2AuthorizationCodeRequestAuth
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authenticationProviders(configureAuthenticationValidator())
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
);
return http.build();
@@ -133,19 +139,22 @@ 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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
deviceAuthorizationEndpoint
.deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter) <1>
.deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.verificationUri("/oauth2/v1/device_verification") <7>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
deviceAuthorizationEndpoint
.deviceAuthorizationRequestConverter(deviceAuthorizationRequestConverter) <1>
.deviceAuthorizationRequestConverters(deviceAuthorizationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.deviceAuthorizationResponseHandler(deviceAuthorizationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.verificationUri("/oauth2/v1/device_verification") <7>
)
);
return http.build();
@@ -182,19 +191,22 @@ 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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
deviceVerificationEndpoint
.deviceVerificationRequestConverter(deviceVerificationRequestConverter) <1>
.deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.deviceVerificationResponseHandler(deviceVerificationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.consentPage("/oauth2/v1/consent") <7>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
deviceVerificationEndpoint
.deviceVerificationRequestConverter(deviceVerificationRequestConverter) <1>
.deviceVerificationRequestConverters(deviceVerificationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.deviceVerificationResponseHandler(deviceVerificationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.consentPage("/oauth2/v1/consent") <7>
)
);
return http.build();
@@ -230,18 +242,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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenRequestConverter(accessTokenRequestConverter) <1>
.accessTokenRequestConverters(accessTokenRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.accessTokenResponseHandler(accessTokenResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenRequestConverter(accessTokenRequestConverter) <1>
.accessTokenRequestConverters(accessTokenRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.accessTokenResponseHandler(accessTokenResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
);
return http.build();
@@ -288,13 +303,16 @@ The following example shows how to configure `OAuth2ClientCredentialsAuthenticat
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.authenticationProviders(configureAuthenticationValidator())
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
);
return http.build();
@@ -344,18 +362,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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
tokenIntrospectionEndpoint
.introspectionRequestConverter(introspectionRequestConverter) <1>
.introspectionRequestConverters(introspectionRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.introspectionResponseHandler(introspectionResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenIntrospectionEndpoint(tokenIntrospectionEndpoint ->
tokenIntrospectionEndpoint
.introspectionRequestConverter(introspectionRequestConverter) <1>
.introspectionRequestConverters(introspectionRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.introspectionResponseHandler(introspectionResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
);
return http.build();
@@ -391,18 +412,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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.tokenRevocationEndpoint(tokenRevocationEndpoint ->
tokenRevocationEndpoint
.revocationRequestConverter(revocationRequestConverter) <1>
.revocationRequestConverters(revocationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.revocationResponseHandler(revocationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenRevocationEndpoint(tokenRevocationEndpoint ->
tokenRevocationEndpoint
.revocationRequestConverter(revocationRequestConverter) <1>
.revocationRequestConverters(revocationRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.revocationResponseHandler(revocationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
);
return http.build();
@@ -438,13 +462,17 @@ It defines an extension point that lets you customize the https://datatracker.ie
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
authorizationServerMetadataEndpoint
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer)); <1>
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationServerMetadataEndpoint(authorizationServerMetadataEndpoint ->
authorizationServerMetadataEndpoint
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer) <1>
)
);
return http.build();
}
@@ -478,16 +506,19 @@ It defines an extension point that lets you customize the https://openid.net/spe
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.oidc(oidc ->
oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint ->
providerConfigurationEndpoint
.providerConfigurationCustomizer(providerConfigurationCustomizer) <1>
)
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.providerConfigurationEndpoint(providerConfigurationEndpoint ->
providerConfigurationEndpoint
.providerConfigurationCustomizer(providerConfigurationCustomizer) <1>
)
)
);
return http.build();
@@ -511,21 +542,24 @@ 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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.oidc(oidc ->
oidc
.logoutEndpoint(logoutEndpoint ->
logoutEndpoint
.logoutRequestConverter(logoutRequestConverter) <1>
.logoutRequestConverters(logoutRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.logoutResponseHandler(logoutResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.logoutEndpoint(logoutEndpoint ->
logoutEndpoint
.logoutRequestConverter(logoutRequestConverter) <1>
.logoutRequestConverters(logoutRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.logoutResponseHandler(logoutResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
)
);
return http.build();
@@ -576,14 +610,19 @@ The following example shows how to configure `OidcLogoutAuthenticationProvider`
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.oidc(oidc ->
oidc
.logoutEndpoint(logoutEndpoint ->
logoutEndpoint.authenticationProviders(configureAuthenticationValidator()))
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.logoutEndpoint(logoutEndpoint ->
logoutEndpoint
.authenticationProviders(configureAuthenticationValidator())
)
)
);
return http.build();
@@ -626,22 +665,25 @@ 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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.oidc(oidc ->
oidc
.userInfoEndpoint(userInfoEndpoint ->
userInfoEndpoint
.userInfoRequestConverter(userInfoRequestConverter) <1>
.userInfoRequestConverters(userInfoRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.userInfoResponseHandler(userInfoResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.userInfoMapper(userInfoMapper) <7>
)
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.userInfoEndpoint(userInfoEndpoint ->
userInfoEndpoint
.userInfoRequestConverter(userInfoRequestConverter) <1>
.userInfoRequestConverters(userInfoRequestConvertersConsumer) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.userInfoResponseHandler(userInfoResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
.userInfoMapper(userInfoMapper) <7>
)
)
);
return http.build();
@@ -669,31 +711,9 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
You can customize the ID Token by providing an xref:core-model-components.adoc#oauth2-token-customizer[`OAuth2TokenCustomizer<JwtEncodingContext>`] `@Bean`.
The OpenID Connect 1.0 UserInfo endpoint is an OAuth2 protected resource, which *REQUIRES* an access token to be sent as a bearer token in the https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest[UserInfo request].
The following example shows how to enable the OAuth2 resource server configuration:
[source,java]
----
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
...
http.oauth2ResourceServer(resourceServer -> resourceServer.jwt(Customizer.withDefaults()));
return http.build();
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
----
[NOTE]
A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 UserInfo endpoint.
OAuth2 resource server support is autoconfigured, however, a `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 UserInfo endpoint.
[TIP]
The guide xref:guides/how-to-userinfo.adoc[How-to: Customize the OpenID Connect 1.0 UserInfo response] contains examples of customizing the UserInfo endpoint.
@@ -711,21 +731,24 @@ 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);
OAuth2AuthorizationServerConfigurer.authorizationServer();
authorizationServerConfigurer
.oidc(oidc ->
oidc
.clientRegistrationEndpoint(clientRegistrationEndpoint ->
clientRegistrationEndpoint
.clientRegistrationRequestConverter(clientRegistrationRequestConverter) <1>
.clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(oidc ->
oidc
.clientRegistrationEndpoint(clientRegistrationEndpoint ->
clientRegistrationEndpoint
.clientRegistrationRequestConverter(clientRegistrationRequestConverter) <1>
.clientRegistrationRequestConverters(clientRegistrationRequestConvertersConsumers) <2>
.authenticationProvider(authenticationProvider) <3>
.authenticationProviders(authenticationProvidersConsumer) <4>
.clientRegistrationResponseHandler(clientRegistrationResponseHandler) <5>
.errorResponseHandler(errorResponseHandler) <6>
)
)
);
return http.build();
@@ -756,34 +779,11 @@ The OpenID Connect 1.0 Client Registration endpoint is disabled by default becau
The OpenID Connect 1.0 Client Registration endpoint is an https://openid.net/specs/openid-connect-registration-1_0.html#ClientRegistration[OAuth2 protected resource], which *REQUIRES* an access token to be sent as a bearer token in the Client Registration (or Client Read) request.
[NOTE]
OAuth2 resource server support is autoconfigured, however, a `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint.
[IMPORTANT]
The access token in a Client Registration request *REQUIRES* the OAuth2 scope `client.create`.
[IMPORTANT]
The access token in a Client Read request *REQUIRES* the OAuth2 scope `client.read`.
The following example shows how to enable the OAuth2 resource server configuration:
[source,java]
----
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
...
http.oauth2ResourceServer(resourceServer -> resourceServer.jwt(Customizer.withDefaults()));
return http.build();
}
@Bean
public JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
----
[NOTE]
A `JwtDecoder` `@Bean` is *REQUIRED* for the OpenID Connect 1.0 Client Registration endpoint.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,6 @@ import org.springframework.security.oauth2.server.authorization.token.OAuth2Acce
import org.springframework.security.oauth2.server.authorization.token.OAuth2RefreshTokenGenerator;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.RequestMatcher;
@Configuration
@EnableWebSecurity
@@ -53,29 +52,24 @@ public class SecurityConfig {
OAuth2TokenGenerator<?> tokenGenerator) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenRequestConverter( // <1>
new CustomCodeGrantAuthenticationConverter())
.authenticationProvider( // <2>
new CustomCodeGrantAuthenticationProvider(
authorizationService, tokenGenerator)));
// @fold:on
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenEndpoint(tokenEndpoint ->
tokenEndpoint
.accessTokenRequestConverter( // <1>
new CustomCodeGrantAuthenticationConverter())
.authenticationProvider( // <2>
new CustomCodeGrantAuthenticationProvider(
authorizationService, tokenGenerator)))
)
.authorizeHttpRequests(authorize ->
authorize
.anyRequest().authenticated()
)
.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
// @fold:off
);
return http.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -61,11 +61,16 @@ public class SecurityConfig {
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
)
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
@@ -73,10 +78,7 @@ public class SecurityConfig {
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer((resourceServer) -> resourceServer
.jwt(Customizer.withDefaults()));
);
// @formatter:on
return http.build();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.http.MediaType;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@@ -40,11 +39,16 @@ public class SecurityConfig {
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
// @fold:on
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
)
// Redirect to the login page when not authenticated from the
// authorization endpoint
.exceptionHandling((exceptions) -> exceptions
@@ -52,9 +56,7 @@ public class SecurityConfig {
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
);
// @formatter:on
// @fold:off
@@ -92,4 +94,4 @@ public class SecurityConfig {
return source;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,10 +17,8 @@ package sample.registration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.web.SecurityFilterChain;
@@ -32,14 +30,22 @@ public class SecurityConfig {
@Bean
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(oidc -> oidc.clientRegistrationEndpoint(clientRegistrationEndpoint -> { // <1>
clientRegistrationEndpoint
.authenticationProviders(configureCustomClientMetadataConverters()); // <2>
}));
http.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer.jwt(Customizer.withDefaults()));
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc.clientRegistrationEndpoint((clientRegistrationEndpoint) -> // <1>
clientRegistrationEndpoint
.authenticationProviders(configureCustomClientMetadataConverters()) // <2>
)
)
);
// @formatter:on
return http.build();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,7 +22,6 @@ import org.springframework.http.MediaType;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configuration.OAuth2AuthorizationServerConfiguration;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
@@ -36,11 +35,16 @@ public class SecurityConfig {
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http)
throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
)
// Redirect to the OAuth 2.0 Login endpoint when not authenticated
// from the authorization endpoint
.exceptionHandling((exceptions) -> exceptions
@@ -48,9 +52,7 @@ public class SecurityConfig {
new LoginUrlAuthenticationEntryPoint("/oauth2/authorization/my-client"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults()));
);
// @formatter:on
return http.build();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,12 +60,16 @@ public class EnableUserInfoSecurityConfig {
@Bean // <1>
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
http
.oauth2ResourceServer((oauth2) -> oauth2.jwt(Customizer.withDefaults())) // <2>
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // <2>
)
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -57,50 +57,44 @@ import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
@Configuration(proxyBeanMethods = false)
@EnableWebSecurity
public class JwtUserInfoMapperSecurityConfig {
@Bean // <1>
@Bean // <1>
@Order(1)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
RequestMatcher endpointsMatcher = authorizationServerConfigurer
.getEndpointsMatcher();
Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> { // <2>
Function<OidcUserInfoAuthenticationContext, OidcUserInfo> userInfoMapper = (context) -> { // <2>
OidcUserInfoAuthenticationToken authentication = context.getAuthentication();
JwtAuthenticationToken principal = (JwtAuthenticationToken) authentication.getPrincipal();
return new OidcUserInfo(principal.getToken().getClaims());
};
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
authorizationServerConfigurer
.oidc((oidc) -> oidc
.userInfoEndpoint((userInfo) -> userInfo
.userInfoMapper(userInfoMapper) // <3>
)
);
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) -> oidc // <3>
.userInfoEndpoint((userInfo) -> userInfo
.userInfoMapper(userInfoMapper) // <4>
)
)
)
.authorizeHttpRequests((authorize) -> authorize
.anyRequest().authenticated()
)
.csrf(csrf -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer(resourceServer -> resourceServer
.jwt(Customizer.withDefaults()) // <4>
)
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
.apply(authorizationServerConfigurer); // <5>
);
// @formatter:on
return http.build();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2023 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -196,20 +196,21 @@ public class JpaTests {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
)
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
.oauth2ResourceServer((resourceServer) -> resourceServer
.jwt(Customizer.withDefaults())
);
// @formatter:on
return http.build();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2022 the original author or authors.
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,13 +30,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer;
import org.springframework.security.oauth2.server.authorization.settings.AuthorizationServerSettings;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.RequestMatcher;
/**
* {@link Configuration} for OAuth 2.0 Authorization Server support.
@@ -51,26 +52,40 @@ public class OAuth2AuthorizationServerConfiguration {
@Bean
@Order(Ordered.HIGHEST_PRECEDENCE)
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
applyDefaultSecurity(http);
// @formatter:off
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, Customizer.withDefaults())
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
);
// @formatter:on
return http.build();
}
// @formatter:off
/**
* @param http the {@link HttpSecurity}
* @throws Exception if {@link OAuth2AuthorizationServerConfigurer} could not be
* applied
* @deprecated For removal in 2.0. Use
* {@link HttpSecurity#with(SecurityConfigurerAdapter, Customizer)} and pass in
* {@link OAuth2AuthorizationServerConfigurer#authorizationServer()}.
*/
@Deprecated(since = "1.4", forRemoval = true)
public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
// @formatter:off
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
RequestMatcher endpointsMatcher = authorizationServerConfigurer
.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, Customizer.withDefaults())
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
// @formatter:on
}
// @formatter:on
public static JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
Set<JWSAlgorithm> jwsAlgs = new HashSet<>();

View File

@@ -87,6 +87,17 @@ public final class OAuth2AuthorizationServerConfigurer
private RequestMatcher endpointsMatcher;
/**
* Returns a new instance of {@link OAuth2AuthorizationServerConfigurer} for
* configuring.
* @return a new instance of {@link OAuth2AuthorizationServerConfigurer} for
* configuring
* @since 1.4
*/
public static OAuth2AuthorizationServerConfigurer authorizationServer() {
return new OAuth2AuthorizationServerConfigurer();
}
/**
* Sets the repository of registered clients.
* @param registeredClientRepository the repository of registered clients
@@ -277,7 +288,7 @@ public final class OAuth2AuthorizationServerConfigurer
}
@Override
public void init(HttpSecurity httpSecurity) {
public void init(HttpSecurity httpSecurity) throws Exception {
AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils
.getAuthorizationServerSettings(httpSecurity);
validateAuthorizationServerSettings(authorizationServerSettings);
@@ -339,6 +350,20 @@ public final class OAuth2AuthorizationServerConfigurer
getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class),
getRequestMatcher(OAuth2DeviceAuthorizationEndpointConfigurer.class)));
}
httpSecurity.csrf((csrf) -> csrf.ignoringRequestMatchers(this.endpointsMatcher));
OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class);
if (oidcConfigurer != null) {
if (oidcConfigurer.getConfigurer(OidcUserInfoEndpointConfigurer.class) != null
|| oidcConfigurer.getConfigurer(OidcClientRegistrationEndpointConfigurer.class) != null) {
httpSecurity
// Accept access tokens for User Info and/or Client Registration
.oauth2ResourceServer(
(oauth2ResourceServer) -> oauth2ResourceServer.jwt(Customizer.withDefaults()));
}
}
}
@Override

View File

@@ -61,6 +61,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.Authentication;
@@ -124,7 +125,6 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
@@ -1149,18 +1149,15 @@ public class OAuth2AuthorizationCodeGrantTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, Customizer.withDefaults())
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.securityContext((securityContext) ->
securityContext.securityContextRepository(securityContextRepository))
.apply(authorizationServerConfigurer);
securityContext.securityContextRepository(securityContextRepository));
return http.build();
}
// @formatter:on
@@ -1212,19 +1209,17 @@ public class OAuth2AuthorizationCodeGrantTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.authorizationEndpoint((authorizationEndpoint) ->
authorizationEndpoint.consentPage(consentPage));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationEndpoint((authorizationEndpoint) ->
authorizationEndpoint.consentPage(consentPage))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on
@@ -1242,19 +1237,17 @@ public class OAuth2AuthorizationCodeGrantTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.authorizationEndpoint((authorizationEndpoint) ->
authorizationEndpoint.authenticationProviders(configureAuthenticationProviders()));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationEndpoint((authorizationEndpoint) ->
authorizationEndpoint.authenticationProviders(configureAuthenticationProviders()))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on
@@ -1331,25 +1324,23 @@ public class OAuth2AuthorizationCodeGrantTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.authorizationEndpoint((authorizationEndpoint) ->
authorizationEndpoint
.authorizationRequestConverter(authorizationRequestConverter)
.authorizationRequestConverters(authorizationRequestConvertersConsumer)
.authenticationProvider(authorizationRequestAuthenticationProvider)
.authenticationProviders(authorizationRequestAuthenticationProvidersConsumer)
.authorizationResponseHandler(authorizationResponseHandler)
.errorResponseHandler(authorizationErrorResponseHandler));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationEndpoint((authorizationEndpoint) ->
authorizationEndpoint
.authorizationRequestConverter(authorizationRequestConverter)
.authorizationRequestConverters(authorizationRequestConvertersConsumer)
.authenticationProvider(authorizationRequestAuthenticationProvider)
.authenticationProviders(authorizationRequestAuthenticationProvidersConsumer)
.authorizationResponseHandler(authorizationResponseHandler)
.errorResponseHandler(authorizationErrorResponseHandler))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on

View File

@@ -49,7 +49,6 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
import org.springframework.security.oauth2.server.authorization.test.SpringTestContext;
import org.springframework.security.oauth2.server.authorization.test.SpringTestContextExtension;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import static org.hamcrest.CoreMatchers.hasItems;
@@ -194,23 +193,18 @@ public class OAuth2AuthorizationServerMetadataTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.authorizationServerMetadataEndpoint((authorizationServerMetadataEndpoint) ->
authorizationServerMetadataEndpoint
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer()));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.authorizationServerMetadataEndpoint((authorizationServerMetadataEndpoint) ->
authorizationServerMetadataEndpoint
.authorizationServerMetadataCustomizer(authorizationServerMetadataCustomizer()))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
);
return http.build();
}
// @formatter:on

View File

@@ -104,7 +104,6 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
@@ -541,25 +540,23 @@ public class OAuth2ClientCredentialsGrantTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.tokenEndpoint((tokenEndpoint) ->
tokenEndpoint
.accessTokenRequestConverter(authenticationConverter)
.accessTokenRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.accessTokenResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenEndpoint((tokenEndpoint) ->
tokenEndpoint
.accessTokenRequestConverter(authenticationConverter)
.accessTokenRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.accessTokenResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on
@@ -587,25 +584,23 @@ public class OAuth2ClientCredentialsGrantTests {
authenticationSuccessHandler = spy(authenticationSuccessHandler());
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.clientAuthentication((clientAuthentication) ->
clientAuthentication
.authenticationConverter(authenticationConverter)
.authenticationConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.authenticationSuccessHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.clientAuthentication((clientAuthentication) ->
clientAuthentication
.authenticationConverter(authenticationConverter)
.authenticationConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.authenticationSuccessHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on

View File

@@ -91,7 +91,6 @@ import org.springframework.security.oauth2.server.authorization.token.JwtEncodin
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.Assert;
@@ -373,24 +372,21 @@ public class OAuth2RefreshTokenGrantTests {
HttpSecurity http, RegisteredClientRepository registeredClientRepository) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.clientAuthentication((clientAuthentication) ->
clientAuthentication
.authenticationConverter(
new PublicClientRefreshTokenAuthenticationConverter())
.authenticationProvider(
new PublicClientRefreshTokenAuthenticationProvider(registeredClientRepository))
);
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.clientAuthentication((clientAuthentication) ->
clientAuthentication
.authenticationConverter(
new PublicClientRefreshTokenAuthenticationConverter())
.authenticationProvider(
new PublicClientRefreshTokenAuthenticationProvider(registeredClientRepository)))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on

View File

@@ -98,7 +98,6 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
@@ -576,25 +575,23 @@ public class OAuth2TokenIntrospectionTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.tokenIntrospectionEndpoint((tokenIntrospectionEndpoint) ->
tokenIntrospectionEndpoint
.introspectionRequestConverter(authenticationConverter)
.introspectionRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.introspectionResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenIntrospectionEndpoint((tokenIntrospectionEndpoint) ->
tokenIntrospectionEndpoint
.introspectionRequestConverter(authenticationConverter)
.introspectionRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.introspectionResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on

View File

@@ -77,7 +77,6 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -376,25 +375,23 @@ public class OAuth2TokenRevocationTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.tokenRevocationEndpoint((tokenRevocationEndpoint) ->
tokenRevocationEndpoint
.revocationRequestConverter(authenticationConverter)
.revocationRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.revocationResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenRevocationEndpoint((tokenRevocationEndpoint) ->
tokenRevocationEndpoint
.revocationRequestConverter(authenticationConverter)
.revocationRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.revocationResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on

View File

@@ -104,7 +104,6 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.CollectionUtils;
@@ -615,32 +614,27 @@ public class OidcClientRegistrationTests {
@Override
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.oidc((oidc) ->
oidc
.clientRegistrationEndpoint((clientRegistration) ->
clientRegistration
.clientRegistrationRequestConverter(authenticationConverter)
.clientRegistrationRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.clientRegistrationResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler)
)
);
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc
.clientRegistrationEndpoint((clientRegistration) ->
clientRegistration
.clientRegistrationRequestConverter(authenticationConverter)
.clientRegistrationRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.clientRegistrationResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler)
)
)
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer((resourceServer) ->
resourceServer.jwt(Customizer.withDefaults())
)
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on
@@ -656,27 +650,22 @@ public class OidcClientRegistrationTests {
@Override
public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.oidc((oidc) ->
oidc
.clientRegistrationEndpoint((clientRegistration) ->
clientRegistration
.authenticationProviders(configureClientRegistrationConverters())
)
);
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc
.clientRegistrationEndpoint((clientRegistration) ->
clientRegistration
.authenticationProviders(configureClientRegistrationConverters())
)
)
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer((resourceServer) ->
resourceServer.jwt(Customizer.withDefaults())
)
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on
@@ -704,22 +693,19 @@ public class OidcClientRegistrationTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
authorizationServerConfigurer
.oidc((oidc) ->
oidc.clientRegistrationEndpoint(Customizer.withDefaults()));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc
.clientRegistrationEndpoint(Customizer.withDefaults())
)
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer((resourceServer) ->
resourceServer.jwt(Customizer.withDefaults())
)
.apply(authorizationServerConfigurer);
);
return http.build();
}
// @formatter:on

View File

@@ -17,6 +17,10 @@ package org.springframework.security.oauth2.server.authorization.config.annotati
import java.util.function.Consumer;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
import com.nimbusds.jose.jwk.source.JWKSource;
import com.nimbusds.jose.proc.SecurityContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -30,7 +34,9 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
import org.springframework.security.oauth2.core.oidc.OidcScopes;
import org.springframework.security.oauth2.jose.TestJwks;
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadataClaimNames;
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -42,7 +48,6 @@ import org.springframework.security.oauth2.server.authorization.settings.Authori
import org.springframework.security.oauth2.server.authorization.test.SpringTestContext;
import org.springframework.security.oauth2.server.authorization.test.SpringTestContextExtension;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
@@ -222,9 +227,16 @@ public class OidcProviderConfigurationTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
// Enable OpenID Connect 1.0
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = OAuth2AuthorizationServerConfigurer
.authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
);
// @formatter:on
return http.build();
}
@@ -234,6 +246,16 @@ public class OidcProviderConfigurationTests {
return new InMemoryRegisteredClientRepository(registeredClient);
}
@Bean
JWKSource<SecurityContext> jwkSource() {
return new ImmutableJWKSet<>(new JWKSet(TestJwks.DEFAULT_RSA_JWK));
}
@Bean
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
}
@Bean
AuthorizationServerSettings authorizationServerSettings() {
return AuthorizationServerSettings.builder().issuer(ISSUER).build();
@@ -261,24 +283,19 @@ public class OidcProviderConfigurationTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.oidc((oidc) ->
oidc.providerConfigurationEndpoint((providerConfigurationEndpoint) ->
providerConfigurationEndpoint
.providerConfigurationCustomizer(providerConfigurationCustomizer())));
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc.providerConfigurationEndpoint((providerConfigurationEndpoint) ->
providerConfigurationEndpoint
.providerConfigurationCustomizer(providerConfigurationCustomizer())))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
);
return http.build();
}
// @formatter:on
@@ -298,14 +315,15 @@ public class OidcProviderConfigurationTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.oidc((oidc) ->
oidc.clientRegistrationEndpoint(Customizer.withDefaults())
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc.clientRegistrationEndpoint(Customizer.withDefaults())
)
);
return http.build();
}
// @formatter:on

View File

@@ -96,7 +96,6 @@ import org.springframework.security.oauth2.server.authorization.token.OAuth2Toke
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenGenerator;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.util.LinkedMultiValueMap;
@@ -599,9 +598,16 @@ public class OidcTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
// Enable OpenID Connect 1.0
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class).oidc(Customizer.withDefaults());
// @formatter:off
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
);
// @formatter:on
return http.build();
}
@@ -696,23 +702,17 @@ public class OidcTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
// Enable OpenID Connect 1.0
authorizationServerConfigurer
.tokenGenerator(tokenGenerator())
.oidc(Customizer.withDefaults());
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenGenerator(tokenGenerator())
.oidc(Customizer.withDefaults())
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
);
return http.build();
}
// @formatter:on
@@ -743,22 +743,17 @@ public class OidcTests {
@Bean
SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
http.apply(authorizationServerConfigurer);
authorizationServerConfigurer
.tokenGenerator(tokenGenerator())
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.tokenGenerator(tokenGenerator())
.oidc(Customizer.withDefaults())
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher));
);
return http.build();
}
// @formatter:on

View File

@@ -79,7 +79,6 @@ import org.springframework.security.web.authentication.AuthenticationFailureHand
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.context.HttpSessionSecurityContextRepository;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultMatcher;
@@ -405,33 +404,29 @@ public class OidcUserInfoTests {
@Bean
@Override
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
// @formatter:off
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer((resourceServer) ->
resourceServer.jwt(Customizer.withDefaults())
)
.apply(authorizationServerConfigurer)
.oidc((oidc) -> oidc
.userInfoEndpoint((userInfo) -> userInfo
.userInfoRequestConverter(authenticationConverter)
.userInfoRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.userInfoResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler)
.userInfoMapper(userInfoMapper)
)
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc((oidc) ->
oidc
.userInfoEndpoint((userInfo) ->
userInfo
.userInfoRequestConverter(authenticationConverter)
.userInfoRequestConverters(authenticationConvertersConsumer)
.authenticationProvider(authenticationProvider)
.authenticationProviders(authenticationProvidersConsumer)
.userInfoResponseHandler(authenticationSuccessHandler)
.errorResponseHandler(authenticationFailureHandler)
.userInfoMapper(userInfoMapper)))
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
);
// @formatter:on
return http.build();
}
@@ -445,24 +440,20 @@ public class OidcUserInfoTests {
@Bean
@Override
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
// Enable OpenID Connect 1.0
authorizationServerConfigurer.oidc(Customizer.withDefaults());
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
// @formatter:off
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer((resourceServer) ->
resourceServer.jwt(Customizer.withDefaults())
)
.securityContext((securityContext) ->
securityContext.securityContextRepository(securityContextRepository))
.apply(authorizationServerConfigurer);
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults())
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.securityContext((securityContext) ->
securityContext.securityContextRepository(securityContextRepository));
// @formatter:on
return http.build();
@@ -476,22 +467,18 @@ public class OidcUserInfoTests {
@Bean
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = new OAuth2AuthorizationServerConfigurer();
// Enable OpenID Connect 1.0
authorizationServerConfigurer.oidc(Customizer.withDefaults());
RequestMatcher endpointsMatcher = authorizationServerConfigurer.getEndpointsMatcher();
// @formatter:off
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
OAuth2AuthorizationServerConfigurer.authorizationServer();
http
.securityMatcher(endpointsMatcher)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
.oauth2ResourceServer((resourceServer) ->
resourceServer.jwt(Customizer.withDefaults())
)
.apply(authorizationServerConfigurer);
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.oidc(Customizer.withDefaults())
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
);
// @formatter:on
return http.build();

View File

@@ -57,6 +57,8 @@ import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
import static org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer.authorizationServer;
/**
* @author Joe Grandja
* @author Daniel Garnier-Moiroux
@@ -73,8 +75,6 @@ public class AuthorizationServerConfig {
HttpSecurity http, RegisteredClientRepository registeredClientRepository,
AuthorizationServerSettings authorizationServerSettings) throws Exception {
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
/*
* This sample demonstrates the use of a public client that does not
* store credentials or authenticate with the authorization server.
@@ -97,34 +97,39 @@ public class AuthorizationServerConfig {
DeviceClientAuthenticationProvider deviceClientAuthenticationProvider =
new DeviceClientAuthenticationProvider(registeredClientRepository);
// @formatter:off
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
deviceAuthorizationEndpoint.verificationUri("/activate")
)
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)
)
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationConverter(deviceClientAuthenticationConverter)
.authenticationProvider(deviceClientAuthenticationProvider)
)
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
// @formatter:on
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = authorizationServer();
// @formatter:off
http
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
.with(authorizationServerConfigurer, (authorizationServer) ->
authorizationServer
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
deviceAuthorizationEndpoint.verificationUri("/activate")
)
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)
)
.clientAuthentication(clientAuthentication ->
clientAuthentication
.authenticationConverter(deviceClientAuthenticationConverter)
.authenticationProvider(deviceClientAuthenticationProvider)
)
.authorizationEndpoint(authorizationEndpoint ->
authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
)
.authorizeHttpRequests((authorize) ->
authorize.anyRequest().authenticated()
)
// Redirect to the /login page when not authenticated from the authorization endpoint
// NOTE: DefaultSecurityConfig is configured with formLogin.loginPage("/login")
.exceptionHandling((exceptions) -> exceptions
.defaultAuthenticationEntryPointFor(
new LoginUrlAuthenticationEntryPoint("/login"),
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
)
)
.oauth2ResourceServer(oauth2ResourceServer ->
oauth2ResourceServer.jwt(Customizer.withDefaults()));
);
// @formatter:on
return http.build();
}