Merge AuthorizationCodeGrantConfigurer -> OAuth2LoginConfigurer

Fixes gh-4684
This commit is contained in:
Joe Grandja 2017-10-24 12:56:18 -04:00
parent a7ba02bdef
commit 09a94a4ef4
2 changed files with 82 additions and 236 deletions

View File

@ -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<B extends HttpSecurityBuilder<B>> extends
AbstractHttpConfigurer<AuthorizationCodeGrantConfigurer<B>, 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<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
private SecurityTokenRepository<AccessToken> accessTokenRepository;
private JwtDecoderRegistry jwtDecoderRegistry;
public AuthorizationCodeGrantConfigurer<B> authorizationRequestBaseUri(String authorizationRequestBaseUri) {
Assert.hasText(authorizationRequestBaseUri, "authorizationRequestBaseUri cannot be empty");
this.authorizationRequestBaseUri = authorizationRequestBaseUri;
return this;
}
public AuthorizationCodeGrantConfigurer<B> authorizationRequestUriBuilder(AuthorizationRequestUriBuilder authorizationRequestUriBuilder) {
Assert.notNull(authorizationRequestUriBuilder, "authorizationRequestUriBuilder cannot be null");
this.authorizationRequestUriBuilder = authorizationRequestUriBuilder;
return this;
}
public AuthorizationCodeGrantConfigurer<B> authorizationRequestRepository(AuthorizationRequestRepository authorizationRequestRepository) {
Assert.notNull(authorizationRequestRepository, "authorizationRequestRepository cannot be null");
this.authorizationRequestRepository = authorizationRequestRepository;
return this;
}
public AuthorizationCodeGrantConfigurer<B> authorizationResponseBaseUri(String authorizationResponseBaseUri) {
Assert.hasText(authorizationResponseBaseUri, "authorizationResponseBaseUri cannot be empty");
this.authorizationResponseBaseUri = authorizationResponseBaseUri;
return this;
}
public AuthorizationCodeGrantConfigurer<B> authorizationCodeTokenExchanger(
AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger) {
Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null");
this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger;
return this;
}
public AuthorizationCodeGrantConfigurer<B> accessTokenRepository(SecurityTokenRepository<AccessToken> accessTokenRepository) {
Assert.notNull(accessTokenRepository, "accessTokenRepository cannot be null");
this.accessTokenRepository = accessTokenRepository;
return this;
}
public AuthorizationCodeGrantConfigurer<B> jwtDecoderRegistry(JwtDecoderRegistry jwtDecoderRegistry) {
Assert.notNull(jwtDecoderRegistry, "jwtDecoderRegistry cannot be null");
this.jwtDecoderRegistry = jwtDecoderRegistry;
return this;
}
public AuthorizationCodeGrantConfigurer<B> 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<AuthorizationCodeAuthenticationToken> 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);
}
}

View File

@ -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<B extends HttpSecurityBuilder<B>> exten
AbstractAuthenticationFilterConfigurer<B, OAuth2LoginConfigurer<B>, AuthorizationCodeAuthenticationFilter> {
private static final String DEFAULT_LOGIN_PROCESSING_URI = "/login/oauth2/authorize/code/*";
private final AuthorizationCodeGrantConfigurer<B> 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<B extends HttpSecurityBuilder<B>> 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<B extends HttpSecurityBuilder<B>> exten
}
public class TokenEndpointConfig {
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
private SecurityTokenRepository<AccessToken> accessTokenRepository;
private JwtDecoderRegistry jwtDecoderRegistry;
private TokenEndpointConfig() {
}
@ -133,13 +143,19 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger) {
Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null");
authorizationCodeGrantConfigurer.authorizationCodeTokenExchanger(authorizationCodeTokenExchanger);
this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger;
return this;
}
public TokenEndpointConfig accessTokenRepository(SecurityTokenRepository<AccessToken> 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<B extends HttpSecurityBuilder<B>> 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<B extends HttpSecurityBuilder<B>> exten
@Override
public void init(B http) throws Exception {
super.init(http);
this.authorizationCodeGrantConfigurer.setBuilder(http);
this.authorizationCodeGrantConfigurer.init(http);
AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> 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<B extends HttpSecurityBuilder<B>> exten
userService = new DefaultOAuth2UserService();
}
}
OAuth2UserAuthenticationProvider oauth2UserAuthenticationProvider =
new OAuth2UserAuthenticationProvider(userService);
if (this.userInfoEndpointConfig.userAuthoritiesMapper != null) {
@ -232,6 +275,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> 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<B extends HttpSecurityBuilder<B>> 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<B extends HttpSecurityBuilder<B>> 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<String, String> authenticationUrlToClientName = new HashMap<>();
@ -295,23 +364,4 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
loginPageGeneratingFilter.setLoginPageUrl(this.getLoginPage());
loginPageGeneratingFilter.setFailureUrl(this.getFailureUrl());
}
private class AuthorizationCodeGrantLoginConfigurer extends AuthorizationCodeGrantConfigurer<B> {
@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());
}
}
}
}