Skip to content

Commit 96ab59d

Browse files
committed
Simplify configuring authorization server using HttpSecurity.with()
Closes gh-1707
1 parent 4d1e2d9 commit 96ab59d

File tree

4 files changed

+82
-26
lines changed

4 files changed

+82
-26
lines changed

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configuration/OAuth2AuthorizationServerConfiguration.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2022 the original author or authors.
2+
* Copyright 2020-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,8 @@
3030
import org.springframework.context.annotation.Configuration;
3131
import org.springframework.core.Ordered;
3232
import org.springframework.core.annotation.Order;
33+
import org.springframework.security.config.Customizer;
34+
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
3335
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
3436
import org.springframework.security.oauth2.jwt.JwtDecoder;
3537
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
@@ -55,8 +57,16 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
5557
return http.build();
5658
}
5759

58-
// @formatter:off
60+
/**
61+
* @param http the {@link HttpSecurity}
62+
* @throws Exception if the configurer could not be applied
63+
* @deprecated For removal in 2.0. Use
64+
* {@link HttpSecurity#with(SecurityConfigurerAdapter, Customizer)} and pass in
65+
* {@link OAuth2AuthorizationServerConfigurer#authorizationServer()}.
66+
*/
67+
@Deprecated(since = "1.4", forRemoval = true)
5968
public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
69+
// @formatter:off
6070
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
6171
new OAuth2AuthorizationServerConfigurer();
6272
RequestMatcher endpointsMatcher = authorizationServerConfigurer
@@ -69,8 +79,8 @@ public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
6979
)
7080
.csrf((csrf) -> csrf.ignoringRequestMatchers(endpointsMatcher))
7181
.apply(authorizationServerConfigurer);
82+
// @formatter:on
7283
}
73-
// @formatter:on
7484

7585
public static JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
7686
Set<JWSAlgorithm> jwsAlgs = new HashSet<>();

oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OAuth2AuthorizationServerConfigurer.java

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ public final class OAuth2AuthorizationServerConfigurer
8787

8888
private RequestMatcher endpointsMatcher;
8989

90+
/**
91+
* Returns a new instance of {@link OAuth2AuthorizationServerConfigurer} for
92+
* configuring.
93+
* @return a new instance of {@link OAuth2AuthorizationServerConfigurer} for
94+
* configuring
95+
* @since 1.4
96+
*/
97+
public static OAuth2AuthorizationServerConfigurer authorizationServer() {
98+
return new OAuth2AuthorizationServerConfigurer();
99+
}
100+
90101
/**
91102
* Sets the repository of registered clients.
92103
* @param registeredClientRepository the repository of registered clients
@@ -277,7 +288,7 @@ public RequestMatcher getEndpointsMatcher() {
277288
}
278289

279290
@Override
280-
public void init(HttpSecurity httpSecurity) {
291+
public void init(HttpSecurity httpSecurity) throws Exception {
281292
AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils
282293
.getAuthorizationServerSettings(httpSecurity);
283294
validateAuthorizationServerSettings(authorizationServerSettings);
@@ -339,6 +350,20 @@ public void init(HttpSecurity httpSecurity) {
339350
getRequestMatcher(OAuth2TokenRevocationEndpointConfigurer.class),
340351
getRequestMatcher(OAuth2DeviceAuthorizationEndpointConfigurer.class)));
341352
}
353+
354+
httpSecurity.csrf((csrf) -> csrf.ignoringRequestMatchers(this.endpointsMatcher));
355+
356+
OidcConfigurer oidcConfigurer = getConfigurer(OidcConfigurer.class);
357+
if (oidcConfigurer != null) {
358+
if (oidcConfigurer.getConfigurer(OidcUserInfoEndpointConfigurer.class) != null
359+
|| oidcConfigurer.getConfigurer(OidcClientRegistrationEndpointConfigurer.class) != null) {
360+
httpSecurity
361+
// Accept access tokens for User Info and/or Client Registration
362+
.oauth2ResourceServer(
363+
(oauth2ResourceServer) -> oauth2ResourceServer.jwt(Customizer.withDefaults()));
364+
365+
}
366+
}
342367
}
343368

344369
@Override

oauth2-authorization-server/src/test/java/org/springframework/security/oauth2/server/authorization/config/annotation/web/configurers/OidcProviderConfigurationTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
import java.util.function.Consumer;
1919

20+
import com.nimbusds.jose.jwk.JWKSet;
21+
import com.nimbusds.jose.jwk.source.ImmutableJWKSet;
22+
import com.nimbusds.jose.jwk.source.JWKSource;
23+
import com.nimbusds.jose.proc.SecurityContext;
2024
import org.junit.jupiter.api.Test;
2125
import org.junit.jupiter.api.extension.ExtendWith;
2226

@@ -30,7 +34,9 @@
3034
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
3135
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
3236
import org.springframework.security.oauth2.core.oidc.OidcScopes;
37+
import org.springframework.security.oauth2.jose.TestJwks;
3338
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
39+
import org.springframework.security.oauth2.jwt.JwtDecoder;
3440
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationServerMetadataClaimNames;
3541
import org.springframework.security.oauth2.server.authorization.client.InMemoryRegisteredClientRepository;
3642
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
@@ -234,6 +240,16 @@ RegisteredClientRepository registeredClientRepository() {
234240
return new InMemoryRegisteredClientRepository(registeredClient);
235241
}
236242

243+
@Bean
244+
JWKSource<SecurityContext> jwkSource() {
245+
return new ImmutableJWKSet<>(new JWKSet(TestJwks.DEFAULT_RSA_JWK));
246+
}
247+
248+
@Bean
249+
JwtDecoder jwtDecoder(JWKSource<SecurityContext> jwkSource) {
250+
return OAuth2AuthorizationServerConfiguration.jwtDecoder(jwkSource);
251+
}
252+
237253
@Bean
238254
AuthorizationServerSettings authorizationServerSettings() {
239255
return AuthorizationServerSettings.builder().issuer(ISSUER).build();

samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@
5757
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
5858
import org.springframework.security.web.util.matcher.MediaTypeRequestMatcher;
5959

60+
import static org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer.authorizationServer;
61+
6062
/**
6163
* @author Joe Grandja
6264
* @author Daniel Garnier-Moiroux
@@ -73,8 +75,6 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(
7375
HttpSecurity http, RegisteredClientRepository registeredClientRepository,
7476
AuthorizationServerSettings authorizationServerSettings) throws Exception {
7577

76-
OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(http);
77-
7878
/*
7979
* This sample demonstrates the use of a public client that does not
8080
* store credentials or authenticate with the authorization server.
@@ -97,34 +97,39 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(
9797
DeviceClientAuthenticationProvider deviceClientAuthenticationProvider =
9898
new DeviceClientAuthenticationProvider(registeredClientRepository);
9999

100-
// @formatter:off
101-
http.getConfigurer(OAuth2AuthorizationServerConfigurer.class)
102-
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
103-
deviceAuthorizationEndpoint.verificationUri("/activate")
104-
)
105-
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
106-
deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)
107-
)
108-
.clientAuthentication(clientAuthentication ->
109-
clientAuthentication
110-
.authenticationConverter(deviceClientAuthenticationConverter)
111-
.authenticationProvider(deviceClientAuthenticationProvider)
112-
)
113-
.authorizationEndpoint(authorizationEndpoint ->
114-
authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))
115-
.oidc(Customizer.withDefaults()); // Enable OpenID Connect 1.0
116-
// @formatter:on
100+
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = authorizationServer();
117101

118102
// @formatter:off
119103
http
104+
.securityMatcher(authorizationServerConfigurer.getEndpointsMatcher())
105+
.with(authorizationServerConfigurer, (authorizationServer) ->
106+
authorizationServer
107+
.deviceAuthorizationEndpoint(deviceAuthorizationEndpoint ->
108+
deviceAuthorizationEndpoint.verificationUri("/activate")
109+
)
110+
.deviceVerificationEndpoint(deviceVerificationEndpoint ->
111+
deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)
112+
)
113+
.clientAuthentication(clientAuthentication ->
114+
clientAuthentication
115+
.authenticationConverter(deviceClientAuthenticationConverter)
116+
.authenticationProvider(deviceClientAuthenticationProvider)
117+
)
118+
.authorizationEndpoint(authorizationEndpoint ->
119+
authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI))
120+
.oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0
121+
)
122+
.authorizeHttpRequests((authorize) ->
123+
authorize.anyRequest().authenticated()
124+
)
125+
// Redirect to the /login page when not authenticated from the authorization endpoint
126+
// NOTE: DefaultSecurityConfig is configured with formLogin.loginPage("/login")
120127
.exceptionHandling((exceptions) -> exceptions
121128
.defaultAuthenticationEntryPointFor(
122129
new LoginUrlAuthenticationEntryPoint("/login"),
123130
new MediaTypeRequestMatcher(MediaType.TEXT_HTML)
124131
)
125-
)
126-
.oauth2ResourceServer(oauth2ResourceServer ->
127-
oauth2ResourceServer.jwt(Customizer.withDefaults()));
132+
);
128133
// @formatter:on
129134
return http.build();
130135
}

0 commit comments

Comments
 (0)