From 09a94a4ef402cbbdd7a6f9c69646067584f22e54 Mon Sep 17 00:00:00 2001 From: Joe Grandja Date: Tue, 24 Oct 2017 12:56:18 -0400 Subject: [PATCH] Merge AuthorizationCodeGrantConfigurer -> OAuth2LoginConfigurer Fixes gh-4684 --- .../AuthorizationCodeGrantConfigurer.java | 204 ------------------ .../oauth2/client/OAuth2LoginConfigurer.java | 114 +++++++--- 2 files changed, 82 insertions(+), 236 deletions(-) delete mode 100644 config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java deleted file mode 100644 index 9fb85dbf50..0000000000 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/AuthorizationCodeGrantConfigurer.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright 2012-2017 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 - * - * http://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 org.springframework.security.config.annotation.web.configurers.oauth2.client; - -import org.springframework.context.ApplicationContext; -import org.springframework.security.authentication.AuthenticationManager; -import org.springframework.security.config.annotation.web.HttpSecurityBuilder; -import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; -import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationProvider; -import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken; -import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger; -import org.springframework.security.oauth2.client.authentication.NimbusAuthorizationCodeTokenExchanger; -import org.springframework.security.oauth2.client.authentication.jwt.JwtDecoderRegistry; -import org.springframework.security.oauth2.client.authentication.jwt.NimbusJwtDecoderRegistry; -import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; -import org.springframework.security.oauth2.client.token.SecurityTokenRepository; -import org.springframework.security.oauth2.client.web.AuthorizationCodeAuthenticationFilter; -import org.springframework.security.oauth2.client.web.AuthorizationRequestRedirectFilter; -import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; -import org.springframework.security.oauth2.core.endpoint.AuthorizationRequestUriBuilder; -import org.springframework.security.oauth2.core.AccessToken; -import org.springframework.security.oauth2.oidc.client.authentication.OidcAuthorizationCodeAuthenticationProvider; -import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; -import org.springframework.util.Assert; - -/** - * A security configurer for the Authorization Code Grant type. - * - * @author Joe Grandja - * @since 5.0 - */ -public class AuthorizationCodeGrantConfigurer> extends - AbstractHttpConfigurer, B> { - - // ***** Authorization Request members - private AuthorizationRequestRedirectFilter authorizationRequestFilter; - private String authorizationRequestBaseUri; - private AuthorizationRequestUriBuilder authorizationRequestUriBuilder; - private AuthorizationRequestRepository authorizationRequestRepository; - - // ***** Authorization Response members - private AuthorizationCodeAuthenticationFilter authorizationResponseFilter; - private String authorizationResponseBaseUri; - private AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger; - private SecurityTokenRepository accessTokenRepository; - private JwtDecoderRegistry jwtDecoderRegistry; - - public AuthorizationCodeGrantConfigurer authorizationRequestBaseUri(String authorizationRequestBaseUri) { - Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty"); - this.authorizationRequestBaseUri = authorizationRequestBaseUri; - return this; - } - - public AuthorizationCodeGrantConfigurer authorizationRequestUriBuilder(AuthorizationRequestUriBuilder authorizationRequestUriBuilder) { - Assert.notNull(authorizationRequestUriBuilder, "authorizationRequestUriBuilder cannot be null"); - this.authorizationRequestUriBuilder = authorizationRequestUriBuilder; - return this; - } - - public AuthorizationCodeGrantConfigurer authorizationRequestRepository(AuthorizationRequestRepository authorizationRequestRepository) { - Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null"); - this.authorizationRequestRepository = authorizationRequestRepository; - return this; - } - - public AuthorizationCodeGrantConfigurer authorizationResponseBaseUri(String authorizationResponseBaseUri) { - Assert.hasText(authorizationResponseBaseUri, "authorizationResponseBaseUri cannot be empty"); - this.authorizationResponseBaseUri = authorizationResponseBaseUri; - return this; - } - - public AuthorizationCodeGrantConfigurer authorizationCodeTokenExchanger( - AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger) { - - Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); - this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger; - return this; - } - - public AuthorizationCodeGrantConfigurer accessTokenRepository(SecurityTokenRepository accessTokenRepository) { - Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null"); - this.accessTokenRepository = accessTokenRepository; - return this; - } - - public AuthorizationCodeGrantConfigurer jwtDecoderRegistry(JwtDecoderRegistry jwtDecoderRegistry) { - Assert.notNull(jwtDecoderRegistry, "jwtDecoderRegistry cannot be null"); - this.jwtDecoderRegistry = jwtDecoderRegistry; - return this; - } - - public AuthorizationCodeGrantConfigurer clientRegistrationRepository(ClientRegistrationRepository clientRegistrationRepository) { - Assert.notNull(clientRegistrationRepository, "clientRegistrationRepository cannot be null"); - this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); - return this; - } - - @Override - public final void init(B http) throws Exception { - AuthorizationCodeAuthenticationProvider oauth2AuthorizationCodeAuthenticationProvider = - new AuthorizationCodeAuthenticationProvider(this.getAuthorizationCodeTokenExchanger()); - if (this.accessTokenRepository != null) { - oauth2AuthorizationCodeAuthenticationProvider.setAccessTokenRepository(this.accessTokenRepository); - } - http.authenticationProvider(this.postProcess(oauth2AuthorizationCodeAuthenticationProvider)); - - OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenticationProvider = - new OidcAuthorizationCodeAuthenticationProvider( - this.getAuthorizationCodeTokenExchanger(), this.getJwtDecoderRegistry()); - if (this.accessTokenRepository != null) { - oidcAuthorizationCodeAuthenticationProvider.setAccessTokenRepository(this.accessTokenRepository); - } - http.authenticationProvider(this.postProcess(oidcAuthorizationCodeAuthenticationProvider)); - - this.authorizationRequestFilter = new AuthorizationRequestRedirectFilter( - this.authorizationRequestBaseUri != null ? - this.authorizationRequestBaseUri : - AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI, - this.getClientRegistrationRepository()); - if (this.authorizationRequestUriBuilder != null) { - this.authorizationRequestFilter.setAuthorizationRequestUriBuilder(this.authorizationRequestUriBuilder); - } - if (this.authorizationRequestRepository != null) { - this.authorizationRequestFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository); - } - - this.authorizationResponseFilter = new AuthorizationCodeAuthenticationFilter( - this.authorizationResponseBaseUri != null ? - this.authorizationResponseBaseUri : - AuthorizationCodeAuthenticationFilter.DEFAULT_AUTHORIZATION_RESPONSE_BASE_URI); - this.authorizationResponseFilter.setClientRegistrationRepository(this.getClientRegistrationRepository()); - if (this.authorizationRequestRepository != null) { - this.authorizationResponseFilter.setAuthorizationRequestRepository(this.authorizationRequestRepository); - } - } - - @Override - public void configure(B http) throws Exception { - http.addFilter(this.postProcess(this.authorizationRequestFilter)); - - this.authorizationResponseFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class)); - SessionAuthenticationStrategy sessionAuthenticationStrategy = http.getSharedObject(SessionAuthenticationStrategy.class); - if (sessionAuthenticationStrategy != null) { - this.authorizationResponseFilter.setSessionAuthenticationStrategy(sessionAuthenticationStrategy); - } - http.addFilter(this.postProcess(this.authorizationResponseFilter)); - } - - AuthorizationRequestRedirectFilter getAuthorizationRequestFilter() { - return this.authorizationRequestFilter; - } - - String getAuthorizationRequestBaseUri() { - return this.authorizationRequestBaseUri; - } - - String getAuthorizationResponseBaseUri() { - return this.authorizationResponseBaseUri; - } - - AuthorizationRequestRepository getAuthorizationRequestRepository() { - return this.authorizationRequestRepository; - } - - private AuthorizationGrantTokenExchanger getAuthorizationCodeTokenExchanger() { - if (this.authorizationCodeTokenExchanger == null) { - this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger(); - } - return this.authorizationCodeTokenExchanger; - } - - private JwtDecoderRegistry getJwtDecoderRegistry() { - if (this.jwtDecoderRegistry == null) { - this.jwtDecoderRegistry = new NimbusJwtDecoderRegistry(); - } - return this.jwtDecoderRegistry; - } - - private ClientRegistrationRepository getClientRegistrationRepository() { - ClientRegistrationRepository clientRegistrationRepository = this.getBuilder().getSharedObject(ClientRegistrationRepository.class); - if (clientRegistrationRepository == null) { - clientRegistrationRepository = this.getClientRegistrationRepositoryBean(); - this.getBuilder().setSharedObject(ClientRegistrationRepository.class, clientRegistrationRepository); - } - return clientRegistrationRepository; - } - - private ClientRegistrationRepository getClientRegistrationRepositoryBean() { - return this.getBuilder().getSharedObject(ApplicationContext.class).getBean(ClientRegistrationRepository.class); - } -} diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java index a7da870133..adea749fb4 100644 --- a/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java +++ b/config/src/main/java/org/springframework/security/config/annotation/web/configurers/oauth2/client/OAuth2LoginConfigurer.java @@ -20,8 +20,12 @@ import org.springframework.core.ResolvableType; import org.springframework.security.config.annotation.web.HttpSecurityBuilder; import org.springframework.security.config.annotation.web.configurers.AbstractAuthenticationFilterConfigurer; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; +import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationProvider; import org.springframework.security.oauth2.client.authentication.AuthorizationCodeAuthenticationToken; import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger; +import org.springframework.security.oauth2.client.authentication.NimbusAuthorizationCodeTokenExchanger; +import org.springframework.security.oauth2.client.authentication.jwt.JwtDecoderRegistry; +import org.springframework.security.oauth2.client.authentication.jwt.NimbusJwtDecoderRegistry; import org.springframework.security.oauth2.client.authentication.userinfo.CustomUserTypesOAuth2UserService; import org.springframework.security.oauth2.client.authentication.userinfo.DefaultOAuth2UserService; import org.springframework.security.oauth2.client.authentication.userinfo.DelegatingOAuth2UserService; @@ -34,9 +38,10 @@ import org.springframework.security.oauth2.client.token.SecurityTokenRepository; import org.springframework.security.oauth2.client.web.AuthorizationCodeAuthenticationFilter; import org.springframework.security.oauth2.client.web.AuthorizationRequestRedirectFilter; import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; -import org.springframework.security.oauth2.core.endpoint.AuthorizationRequestUriBuilder; import org.springframework.security.oauth2.core.AccessToken; +import org.springframework.security.oauth2.core.endpoint.AuthorizationRequestUriBuilder; import org.springframework.security.oauth2.core.user.OAuth2User; +import org.springframework.security.oauth2.oidc.client.authentication.OidcAuthorizationCodeAuthenticationProvider; import org.springframework.security.oauth2.oidc.client.authentication.userinfo.OidcUserAuthenticationProvider; import org.springframework.security.oauth2.oidc.client.authentication.userinfo.OidcUserService; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; @@ -61,7 +66,6 @@ public final class OAuth2LoginConfigurer> exten AbstractAuthenticationFilterConfigurer, AuthorizationCodeAuthenticationFilter> { private static final String DEFAULT_LOGIN_PROCESSING_URI = "/login/oauth2/authorize/code/*"; - private final AuthorizationCodeGrantConfigurer authorizationCodeGrantConfigurer = new AuthorizationCodeGrantLoginConfigurer(); private final AuthorizationEndpointConfig authorizationEndpointConfig = new AuthorizationEndpointConfig(); private final TokenEndpointConfig tokenEndpointConfig = new TokenEndpointConfig(); private final RedirectionEndpointConfig redirectionEndpointConfig = new RedirectionEndpointConfig(); @@ -93,25 +97,28 @@ public final class OAuth2LoginConfigurer> exten } public class AuthorizationEndpointConfig { + private String authorizationRequestBaseUri; + private AuthorizationRequestUriBuilder authorizationRequestUriBuilder; + private AuthorizationRequestRepository authorizationRequestRepository; private AuthorizationEndpointConfig() { } public AuthorizationEndpointConfig baseUri(String authorizationRequestBaseUri) { Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty"); - authorizationCodeGrantConfigurer.authorizationRequestBaseUri(authorizationRequestBaseUri); + this.authorizationRequestBaseUri = authorizationRequestBaseUri; return this; } public AuthorizationEndpointConfig authorizationRequestUriBuilder(AuthorizationRequestUriBuilder authorizationRequestUriBuilder) { Assert.notNull(authorizationRequestUriBuilder, "authorizationRequestUriBuilder cannot be null"); - authorizationCodeGrantConfigurer.authorizationRequestUriBuilder(authorizationRequestUriBuilder); + this.authorizationRequestUriBuilder = authorizationRequestUriBuilder; return this; } public AuthorizationEndpointConfig authorizationRequestRepository(AuthorizationRequestRepository authorizationRequestRepository) { Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null"); - authorizationCodeGrantConfigurer.authorizationRequestRepository(authorizationRequestRepository); + this.authorizationRequestRepository = authorizationRequestRepository; return this; } @@ -125,6 +132,9 @@ public final class OAuth2LoginConfigurer> exten } public class TokenEndpointConfig { + private AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger; + private SecurityTokenRepository accessTokenRepository; + private JwtDecoderRegistry jwtDecoderRegistry; private TokenEndpointConfig() { } @@ -133,13 +143,19 @@ public final class OAuth2LoginConfigurer> exten AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger) { Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); - authorizationCodeGrantConfigurer.authorizationCodeTokenExchanger(authorizationCodeTokenExchanger); + this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger; return this; } public TokenEndpointConfig accessTokenRepository(SecurityTokenRepository accessTokenRepository) { Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null"); - authorizationCodeGrantConfigurer.accessTokenRepository(accessTokenRepository); + this.accessTokenRepository = accessTokenRepository; + return this; + } + + public TokenEndpointConfig jwtDecoderRegistry(JwtDecoderRegistry jwtDecoderRegistry) { + Assert.notNull(jwtDecoderRegistry, "jwtDecoderRegistry cannot be null"); + this.jwtDecoderRegistry = jwtDecoderRegistry; return this; } @@ -153,13 +169,14 @@ public final class OAuth2LoginConfigurer> exten } public class RedirectionEndpointConfig { + private String authorizationResponseBaseUri; private RedirectionEndpointConfig() { } public RedirectionEndpointConfig baseUri(String authorizationResponseBaseUri) { Assert.hasText(authorizationResponseBaseUri, "authorizationResponseBaseUri cannot be empty"); - authorizationCodeGrantConfigurer.authorizationResponseBaseUri(authorizationResponseBaseUri); + this.authorizationResponseBaseUri = authorizationResponseBaseUri; return this; } @@ -207,8 +224,33 @@ public final class OAuth2LoginConfigurer> exten @Override public void init(B http) throws Exception { super.init(http); - this.authorizationCodeGrantConfigurer.setBuilder(http); - this.authorizationCodeGrantConfigurer.init(http); + + AuthorizationGrantTokenExchanger authorizationCodeTokenExchanger = + this.tokenEndpointConfig.authorizationCodeTokenExchanger; + if (authorizationCodeTokenExchanger == null) { + authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger(); + } + + JwtDecoderRegistry jwtDecoderRegistry = this.tokenEndpointConfig.jwtDecoderRegistry; + if (jwtDecoderRegistry == null) { + jwtDecoderRegistry = new NimbusJwtDecoderRegistry(); + } + + AuthorizationCodeAuthenticationProvider oauth2AuthorizationCodeAuthenticationProvider = + new AuthorizationCodeAuthenticationProvider(authorizationCodeTokenExchanger); + if (this.tokenEndpointConfig.accessTokenRepository != null) { + oauth2AuthorizationCodeAuthenticationProvider.setAccessTokenRepository( + this.tokenEndpointConfig.accessTokenRepository); + } + http.authenticationProvider(this.postProcess(oauth2AuthorizationCodeAuthenticationProvider)); + + OidcAuthorizationCodeAuthenticationProvider oidcAuthorizationCodeAuthenticationProvider = + new OidcAuthorizationCodeAuthenticationProvider(authorizationCodeTokenExchanger, jwtDecoderRegistry); + if (this.tokenEndpointConfig.accessTokenRepository != null) { + oidcAuthorizationCodeAuthenticationProvider.setAccessTokenRepository( + this.tokenEndpointConfig.accessTokenRepository); + } + http.authenticationProvider(this.postProcess(oidcAuthorizationCodeAuthenticationProvider)); OAuth2UserService userService = this.userInfoEndpointConfig.userService; if (userService == null) { @@ -221,6 +263,7 @@ public final class OAuth2LoginConfigurer> exten userService = new DefaultOAuth2UserService(); } } + OAuth2UserAuthenticationProvider oauth2UserAuthenticationProvider = new OAuth2UserAuthenticationProvider(userService); if (this.userInfoEndpointConfig.userAuthoritiesMapper != null) { @@ -232,6 +275,7 @@ public final class OAuth2LoginConfigurer> exten if (userService == null) { userService = new OidcUserService(); } + OidcUserAuthenticationProvider oidcUserAuthenticationProvider = new OidcUserAuthenticationProvider(userService); if (this.userInfoEndpointConfig.userAuthoritiesMapper != null) { @@ -244,7 +288,32 @@ public final class OAuth2LoginConfigurer> exten @Override public void configure(B http) throws Exception { - this.authorizationCodeGrantConfigurer.configure(http); + String authorizationRequestBaseUri = this.authorizationEndpointConfig.authorizationRequestBaseUri; + if (authorizationRequestBaseUri == null) { + authorizationRequestBaseUri = AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI; + } + + AuthorizationRequestRedirectFilter authorizationRequestFilter = new AuthorizationRequestRedirectFilter( + authorizationRequestBaseUri, this.getClientRegistrationRepository()); + if (this.authorizationEndpointConfig.authorizationRequestUriBuilder != null) { + authorizationRequestFilter.setAuthorizationRequestUriBuilder( + this.authorizationEndpointConfig.authorizationRequestUriBuilder); + } + if (this.authorizationEndpointConfig.authorizationRequestRepository != null) { + authorizationRequestFilter.setAuthorizationRequestRepository( + this.authorizationEndpointConfig.authorizationRequestRepository); + } + http.addFilter(this.postProcess(authorizationRequestFilter)); + + AuthorizationCodeAuthenticationFilter authorizationResponseFilter = this.getAuthenticationFilter(); + if (this.redirectionEndpointConfig.authorizationResponseBaseUri != null) { + authorizationResponseFilter.setFilterProcessesUrl(this.redirectionEndpointConfig.authorizationResponseBaseUri); + } + authorizationResponseFilter.setClientRegistrationRepository(this.getClientRegistrationRepository()); + if (this.authorizationEndpointConfig.authorizationRequestRepository != null) { + authorizationResponseFilter.setAuthorizationRequestRepository( + this.authorizationEndpointConfig.authorizationRequestRepository); + } super.configure(http); } @@ -282,8 +351,8 @@ public final class OAuth2LoginConfigurer> exten return; } - String authorizationRequestBaseUri = authorizationCodeGrantConfigurer.getAuthorizationRequestBaseUri() != null ? - authorizationCodeGrantConfigurer.getAuthorizationRequestBaseUri() : + String authorizationRequestBaseUri = this.authorizationEndpointConfig.authorizationRequestBaseUri != null ? + this.authorizationEndpointConfig.authorizationRequestBaseUri : AuthorizationRequestRedirectFilter.DEFAULT_AUTHORIZATION_REQUEST_BASE_URI; Map authenticationUrlToClientName = new HashMap<>(); @@ -295,23 +364,4 @@ public final class OAuth2LoginConfigurer> exten loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage()); loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl()); } - - private class AuthorizationCodeGrantLoginConfigurer extends AuthorizationCodeGrantConfigurer { - - @Override - public void configure(B http) throws Exception { - http.addFilter(OAuth2LoginConfigurer.this.postProcess(this.getAuthorizationRequestFilter())); - - AuthorizationCodeAuthenticationFilter authorizationResponseFilter = getAuthenticationFilter(); - authorizationResponseFilter.setClientRegistrationRepository(getClientRegistrationRepository()); - if (authorizationCodeGrantConfigurer.getAuthorizationResponseBaseUri() != null) { - authorizationResponseFilter.setAuthorizationResponseBaseUri( - authorizationCodeGrantConfigurer.getAuthorizationResponseBaseUri()); - } - if (authorizationCodeGrantConfigurer.getAuthorizationRequestRepository() != null) { - authorizationResponseFilter.setAuthorizationRequestRepository( - authorizationCodeGrantConfigurer.getAuthorizationRequestRepository()); - } - } - } }