Skip to content

Commit

Permalink
Simplify configuring authorization server using HttpSecurity.with()
Browse files Browse the repository at this point in the history
  • Loading branch information
jgrandja committed Sep 19, 2024
1 parent 937e09a commit 20e0c65
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -56,6 +56,7 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(HttpSecurity h
}

// @formatter:off
@Deprecated(since = "1.4", forRemoval = true)
public static void applyDefaultSecurity(HttpSecurity http) throws Exception {
OAuth2AuthorizationServerConfigurer authorizationServerConfigurer =
new OAuth2AuthorizationServerConfigurer();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -277,7 +288,7 @@ public RequestMatcher getEndpointsMatcher() {
}

@Override
public void init(HttpSecurity httpSecurity) {
public void init(HttpSecurity httpSecurity) throws Exception {
AuthorizationServerSettings authorizationServerSettings = OAuth2ConfigurerUtils
.getAuthorizationServerSettings(httpSecurity);
validateAuthorizationServerSettings(authorizationServerSettings);
Expand Down Expand Up @@ -339,6 +350,20 @@ public void init(HttpSecurity httpSecurity) {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

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;

Expand All @@ -30,7 +34,9 @@
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;
Expand Down Expand Up @@ -234,6 +240,16 @@ RegisteredClientRepository registeredClientRepository() {
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
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
Expand All @@ -73,8 +75,6 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(
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.
Expand All @@ -97,34 +97,39 @@ public SecurityFilterChain authorizationServerSecurityFilterChain(
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();
}
Expand Down

0 comments on commit 20e0c65

Please sign in to comment.