From e14e27c342761dab99a99a1873f3848614d3281a Mon Sep 17 00:00:00 2001 From: Joe Grandja <10884212+jgrandja@users.noreply.github.com> Date: Thu, 19 Sep 2024 06:15:57 -0400 Subject: [PATCH] Configure demo-authorizationserver sample with one SecurityFilterChain --- .../config/AuthorizationServerConfig.java | 71 +++++++++----- .../sample/config/DefaultSecurityConfig.java | 92 ------------------- 2 files changed, 48 insertions(+), 115 deletions(-) delete mode 100644 samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java diff --git a/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java b/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java index 91f82e76c..ba7a97365 100644 --- a/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java +++ b/samples/demo-authorizationserver/src/main/java/sample/config/AuthorizationServerConfig.java @@ -22,21 +22,25 @@ import com.nimbusds.jose.jwk.source.JWKSource; import com.nimbusds.jose.proc.SecurityContext; import sample.authentication.DeviceClientAuthenticationProvider; +import sample.federation.FederatedIdentityAuthenticationSuccessHandler; import sample.federation.FederatedIdentityIdTokenCustomizer; import sample.jose.Jwks; import sample.web.authentication.DeviceClientAuthenticationConverter; 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.http.MediaType; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; 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.session.SessionRegistry; +import org.springframework.security.core.session.SessionRegistryImpl; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.oidc.OidcScopes; @@ -47,15 +51,14 @@ import org.springframework.security.oauth2.server.authorization.client.RegisteredClient; import org.springframework.security.oauth2.server.authorization.client.RegisteredClientRepository; 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.oauth2.server.authorization.settings.AuthorizationServerSettings; import org.springframework.security.oauth2.server.authorization.settings.ClientSettings; import org.springframework.security.oauth2.server.authorization.settings.TokenSettings; import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext; import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer; +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.session.HttpSessionEventPublisher; import static org.springframework.security.oauth2.server.authorization.config.annotation.web.configurers.OAuth2AuthorizationServerConfigurer.authorizationServer; @@ -65,12 +68,12 @@ * @author Steve Riesenberg * @since 1.1 */ +@EnableWebSecurity @Configuration(proxyBeanMethods = false) public class AuthorizationServerConfig { private static final String CUSTOM_CONSENT_PAGE_URI = "/oauth2/consent"; @Bean - @Order(Ordered.HIGHEST_PRECEDENCE) public SecurityFilterChain authorizationServerSecurityFilterChain( HttpSecurity http, RegisteredClientRepository registeredClientRepository, AuthorizationServerSettings authorizationServerSettings) throws Exception { @@ -97,43 +100,65 @@ public SecurityFilterChain authorizationServerSecurityFilterChain( DeviceClientAuthenticationProvider deviceClientAuthenticationProvider = new DeviceClientAuthenticationProvider(registeredClientRepository); - OAuth2AuthorizationServerConfigurer authorizationServerConfigurer = authorizationServer(); - // @formatter:off http - .securityMatcher(authorizationServerConfigurer.getEndpointsMatcher()) - .with(authorizationServerConfigurer, (authorizationServer) -> + .with(authorizationServer(), (authorizationServer) -> authorizationServer - .deviceAuthorizationEndpoint(deviceAuthorizationEndpoint -> + .deviceAuthorizationEndpoint((deviceAuthorizationEndpoint) -> deviceAuthorizationEndpoint.verificationUri("/activate") ) - .deviceVerificationEndpoint(deviceVerificationEndpoint -> + .deviceVerificationEndpoint((deviceVerificationEndpoint) -> deviceVerificationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI) ) - .clientAuthentication(clientAuthentication -> + .clientAuthentication((clientAuthentication) -> clientAuthentication .authenticationConverter(deviceClientAuthenticationConverter) .authenticationProvider(deviceClientAuthenticationProvider) ) - .authorizationEndpoint(authorizationEndpoint -> + .authorizationEndpoint((authorizationEndpoint) -> authorizationEndpoint.consentPage(CUSTOM_CONSENT_PAGE_URI)) .oidc(Customizer.withDefaults()) // Enable OpenID Connect 1.0 ) .authorizeHttpRequests((authorize) -> - authorize.anyRequest().authenticated() + authorize + .requestMatchers("/assets/**", "/login").permitAll() + .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) - ) + .formLogin((formLogin) -> + formLogin + .loginPage("/login") + ) + .oauth2Login((oauth2Login) -> + oauth2Login + .loginPage("/login") + .successHandler(new FederatedIdentityAuthenticationSuccessHandler()) ); // @formatter:on return http.build(); } + // @formatter:off + @Bean + public UserDetailsService users() { + UserDetails user = User.withDefaultPasswordEncoder() + .username("user1") + .password("password") + .roles("USER") + .build(); + return new InMemoryUserDetailsManager(user); + } + // @formatter:on + + @Bean + public SessionRegistry sessionRegistry() { + return new SessionRegistryImpl(); + } + + @Bean + public HttpSessionEventPublisher httpSessionEventPublisher() { + return new HttpSessionEventPublisher(); + } + // @formatter:off @Bean public JdbcRegisteredClientRepository registeredClientRepository(JdbcTemplate jdbcTemplate) { diff --git a/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java b/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java deleted file mode 100644 index 7c553744c..000000000 --- a/samples/demo-authorizationserver/src/main/java/sample/config/DefaultSecurityConfig.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2020-2023 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package sample.config; - -import sample.federation.FederatedIdentityAuthenticationSuccessHandler; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.core.session.SessionRegistry; -import org.springframework.security.core.session.SessionRegistryImpl; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.provisioning.InMemoryUserDetailsManager; -import org.springframework.security.web.SecurityFilterChain; -import org.springframework.security.web.authentication.AuthenticationSuccessHandler; -import org.springframework.security.web.session.HttpSessionEventPublisher; - -/** - * @author Joe Grandja - * @author Steve Riesenberg - * @since 1.1 - */ -@EnableWebSecurity -@Configuration(proxyBeanMethods = false) -public class DefaultSecurityConfig { - - // @formatter:off - @Bean - public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { - http - .authorizeHttpRequests(authorize -> - authorize - .requestMatchers("/assets/**", "/login").permitAll() - .anyRequest().authenticated() - ) - .formLogin(formLogin -> - formLogin - .loginPage("/login") - ) - .oauth2Login(oauth2Login -> - oauth2Login - .loginPage("/login") - .successHandler(authenticationSuccessHandler()) - ); - - return http.build(); - } - // @formatter:on - - private AuthenticationSuccessHandler authenticationSuccessHandler() { - return new FederatedIdentityAuthenticationSuccessHandler(); - } - - // @formatter:off - @Bean - public UserDetailsService users() { - UserDetails user = User.withDefaultPasswordEncoder() - .username("user1") - .password("password") - .roles("USER") - .build(); - return new InMemoryUserDetailsManager(user); - } - // @formatter:on - - @Bean - public SessionRegistry sessionRegistry() { - return new SessionRegistryImpl(); - } - - @Bean - public HttpSessionEventPublisher httpSessionEventPublisher() { - return new HttpSessionEventPublisher(); - } - -}