Generalize AuthorizationCodeAuthenticationProvider

The AuthorizationCodeAuthenticationProvider implements part of the
Authorization Code Grant flow as defined in
OAuth 2.0 Authorization Framework and OpenID Connect Core 1.0.
The implementation needs to be de-coupled to allow for better re-use and readability.
This commit introduces the AuthorizationGrantAuthenticator and extracts logic from
AuthorizationCodeAuthenticationProvider and provides different implementations
for OAuth 2.0 and OpenID Connect 1.0.

This re-factor is part of the work required for Issue gh-4513
This commit is contained in:
Joe Grandja
2017-10-04 17:32:02 -04:00
parent f184ada186
commit f8a9077d5a
8 changed files with 311 additions and 110 deletions

View File

@@ -20,6 +20,9 @@ import org.springframework.security.config.annotation.web.configurers.AbstractAu
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.AuthorizationCodeAuthenticator;
import org.springframework.security.oauth2.client.authentication.AuthorizationGrantAuthenticator;
import org.springframework.security.oauth2.client.authentication.DelegatingAuthorizationGrantAuthenticator;
import org.springframework.security.oauth2.client.authentication.jwt.JwtDecoderRegistry;
import org.springframework.security.oauth2.client.authentication.jwt.nimbus.NimbusJwtDecoderRegistry;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
@@ -34,6 +37,7 @@ import org.springframework.security.oauth2.client.web.AuthorizationGrantTokenExc
import org.springframework.security.oauth2.client.web.nimbus.NimbusAuthorizationCodeTokenExchanger;
import org.springframework.security.oauth2.core.AccessToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.security.oauth2.oidc.client.authentication.OidcAuthorizationCodeAuthenticator;
import org.springframework.security.oauth2.oidc.client.user.OidcUserService;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
@@ -51,6 +55,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
AbstractAuthenticationFilterConfigurer<H, AuthorizationCodeAuthenticationFilterConfigurer<H, R>, AuthorizationCodeAuthenticationProcessingFilter> {
private R authorizationResponseMatcher;
private AuthorizationGrantAuthenticator<AuthorizationCodeAuthenticationToken> authorizationCodeAuthenticator;
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger;
private SecurityTokenRepository<AccessToken> accessTokenRepository;
private JwtDecoderRegistry jwtDecoderRegistry;
@@ -124,8 +129,7 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
@Override
public void init(H http) throws Exception {
AuthorizationCodeAuthenticationProvider authenticationProvider = new AuthorizationCodeAuthenticationProvider(
this.getAuthorizationCodeTokenExchanger(), this.getAccessTokenRepository(),
this.getJwtDecoderRegistry(), this.getUserInfoService());
this.getAuthorizationCodeAuthenticator(), this.getAccessTokenRepository(), this.getUserInfoService());
if (this.userAuthoritiesMapper != null) {
authenticationProvider.setAuthoritiesMapper(this.userAuthoritiesMapper);
}
@@ -150,6 +154,17 @@ final class AuthorizationCodeAuthenticationFilterConfigurer<H extends HttpSecuri
this.authorizationResponseMatcher : this.getAuthenticationFilter().getAuthorizationResponseMatcher());
}
private AuthorizationGrantAuthenticator<AuthorizationCodeAuthenticationToken> getAuthorizationCodeAuthenticator() {
if (this.authorizationCodeAuthenticator == null) {
List<AuthorizationGrantAuthenticator<AuthorizationCodeAuthenticationToken>> authenticators = new ArrayList<>();
authenticators.add(new AuthorizationCodeAuthenticator(this.getAuthorizationCodeTokenExchanger()));
authenticators.add(new OidcAuthorizationCodeAuthenticator(
this.getAuthorizationCodeTokenExchanger(), this.getJwtDecoderRegistry()));
this.authorizationCodeAuthenticator = new DelegatingAuthorizationGrantAuthenticator<>(authenticators);;
}
return this.authorizationCodeAuthenticator;
}
private AuthorizationGrantTokenExchanger<AuthorizationCodeAuthenticationToken> getAuthorizationCodeTokenExchanger() {
if (this.authorizationCodeTokenExchanger == null) {
this.authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();