Re-factor AuthorizationGrantTokenExchanger

Fixes gh-4728
This commit is contained in:
Joe Grandja 2017-10-28 12:56:28 -04:00
parent 16e69d06b4
commit 64d8c8b8a9
9 changed files with 143 additions and 38 deletions

View File

@ -62,7 +62,7 @@ import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer; import org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer;
import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger; import org.springframework.security.oauth2.client.endpoint.AuthorizationGrantTokenExchanger;
import org.springframework.security.oauth2.client.endpoint.AuthorizationRequestUriBuilder; import org.springframework.security.oauth2.client.endpoint.AuthorizationRequestUriBuilder;
import org.springframework.security.web.DefaultSecurityFilterChain; import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.PortMapper; import org.springframework.security.web.PortMapper;

View File

@ -24,9 +24,9 @@ import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMap
import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.InMemoryOAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService; import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger; import org.springframework.security.oauth2.client.endpoint.AuthorizationGrantTokenExchanger;
import org.springframework.security.oauth2.client.authentication.NimbusAuthorizationCodeTokenExchanger; import org.springframework.security.oauth2.client.endpoint.NimbusAuthorizationCodeTokenExchanger;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider; import org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider;
import org.springframework.security.oauth2.client.endpoint.AuthorizationRequestUriBuilder; import org.springframework.security.oauth2.client.endpoint.AuthorizationRequestUriBuilder;
import org.springframework.security.oauth2.client.jwt.JwtDecoderRegistry; import org.springframework.security.oauth2.client.jwt.JwtDecoderRegistry;
@ -144,7 +144,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
} }
public class TokenEndpointConfig { public class TokenEndpointConfig {
private AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger; private AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger;
private OAuth2TokenRepository<OAuth2AccessToken> accessTokenRepository; private OAuth2TokenRepository<OAuth2AccessToken> accessTokenRepository;
private JwtDecoderRegistry jwtDecoderRegistry; private JwtDecoderRegistry jwtDecoderRegistry;
@ -152,7 +152,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
} }
public TokenEndpointConfig authorizationCodeTokenExchanger( public TokenEndpointConfig authorizationCodeTokenExchanger(
AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger) { AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger) {
Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null");
this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger; this.authorizationCodeTokenExchanger = authorizationCodeTokenExchanger;
@ -237,7 +237,7 @@ public final class OAuth2LoginConfigurer<B extends HttpSecurityBuilder<B>> exten
public void init(B http) throws Exception { public void init(B http) throws Exception {
super.init(http); super.init(http);
AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger = AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger =
this.tokenEndpointConfig.authorizationCodeTokenExchanger; this.tokenEndpointConfig.authorizationCodeTokenExchanger;
if (authorizationCodeTokenExchanger == null) { if (authorizationCodeTokenExchanger == null) {
authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger(); authorizationCodeTokenExchanger = new NimbusAuthorizationCodeTokenExchanger();

View File

@ -21,6 +21,8 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient; import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.endpoint.AuthorizationGrantTokenExchanger;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest; import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService; import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AccessToken;
@ -60,12 +62,12 @@ import java.util.Collection;
public class OAuth2LoginAuthenticationProvider implements AuthenticationProvider { public class OAuth2LoginAuthenticationProvider implements AuthenticationProvider {
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter"; private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter"; private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
private final AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger; private final AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger;
private final OAuth2UserService<OAuth2UserRequest, OAuth2User> userService; private final OAuth2UserService<OAuth2UserRequest, OAuth2User> userService;
private GrantedAuthoritiesMapper authoritiesMapper = (authorities -> authorities); private GrantedAuthoritiesMapper authoritiesMapper = (authorities -> authorities);
public OAuth2LoginAuthenticationProvider( public OAuth2LoginAuthenticationProvider(
AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger, AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger,
OAuth2UserService<OAuth2UserRequest, OAuth2User> userService) { OAuth2UserService<OAuth2UserRequest, OAuth2User> userService) {
Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null"); Assert.notNull(authorizationCodeTokenExchanger, "authorizationCodeTokenExchanger cannot be null");
@ -110,7 +112,10 @@ public class OAuth2LoginAuthenticationProvider implements AuthenticationProvider
} }
OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse accessTokenResponse =
this.authorizationCodeTokenExchanger.exchange(authorizationCodeAuthentication); this.authorizationCodeTokenExchanger.exchange(
new OAuth2AuthorizationCodeGrantRequest(
authorizationCodeAuthentication.getClientRegistration(),
authorizationCodeAuthentication.getAuthorizationExchange()));
OAuth2AccessToken accessToken = new OAuth2AccessToken(accessTokenResponse.getTokenType(), OAuth2AccessToken accessToken = new OAuth2AccessToken(accessTokenResponse.getTokenType(),
accessTokenResponse.getTokenValue(), accessTokenResponse.getIssuedAt(), accessTokenResponse.getTokenValue(), accessTokenResponse.getIssuedAt(),

View File

@ -0,0 +1,42 @@
/*
* Copyright 2002-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.oauth2.client.endpoint;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.util.Assert;
/**
* Base implementation of an <i>OAuth 2.0 Authorization Grant</i> request
* that holds an <i>authorization grant</i> credential and is used when
* initiating a HTTP request to the Authorization Server's <i>Token Endpoint</i>.
*
* @author Joe Grandja
* @since 5.0
* @see AuthorizationGrantType
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.3">Section 1.3 Authorization Grant</a>
*/
public abstract class AbstractOAuth2AuthorizationGrantRequest {
private final AuthorizationGrantType authorizationGrantType;
protected AbstractOAuth2AuthorizationGrantRequest(AuthorizationGrantType authorizationGrantType) {
Assert.notNull(authorizationGrantType, "authorizationGrantType cannot be null");
this.authorizationGrantType = authorizationGrantType;
}
public AuthorizationGrantType getGrantType() {
return this.authorizationGrantType;
}
}

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.oauth2.client.authentication; package org.springframework.security.oauth2.client.endpoint;
import org.springframework.security.oauth2.core.AuthorizationGrantType; import org.springframework.security.oauth2.core.AuthorizationGrantType;
@ -21,21 +21,21 @@ import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
/** /**
* Implementations of this interface are responsible for <i>&quot;exchanging&quot;</i> * A strategy for <i>&quot;exchanging&quot;</i> an <i>Authorization Grant</i> credential
* an <i>authorization grant</i> credential (for example, an authorization code) for an * (e.g. an Authorization Code) for an <i>Access Token</i> credential
* <i>access token</i> credential at the authorization server's <i>Token Endpoint</i>. * at the Authorization Server's <i>Token Endpoint</i>.
* *
* @author Joe Grandja * @author Joe Grandja
* @since 5.0 * @since 5.0
* @see AuthorizationGrantType * @see AbstractOAuth2AuthorizationGrantRequest
* @see AbstractOAuth2AuthorizationGrantAuthenticationToken
* @see OAuth2AccessTokenResponse * @see OAuth2AccessTokenResponse
* @see AuthorizationGrantType
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.3">Section 1.3 Authorization Grant</a> * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.3">Section 1.3 Authorization Grant</a>
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.3">Section 4.1.3 Access Token Request (Authorization Code Grant)</a> * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.3">Section 4.1.3 Access Token Request (Authorization Code Grant)</a>
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.4">Section 4.1.4 Access Token Response (Authorization Code Grant)</a> * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.4">Section 4.1.4 Access Token Response (Authorization Code Grant)</a>
*/ */
public interface AuthorizationGrantTokenExchanger<T extends AbstractOAuth2AuthorizationGrantAuthenticationToken> { public interface AuthorizationGrantTokenExchanger<T extends AbstractOAuth2AuthorizationGrantRequest> {
OAuth2AccessTokenResponse exchange(T authorizationGrantAuthentication) throws OAuth2AuthenticationException; OAuth2AccessTokenResponse exchange(T authorizationGrantRequest) throws OAuth2AuthenticationException;
} }

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.security.oauth2.client.authentication; package org.springframework.security.oauth2.client.endpoint;
import com.nimbusds.oauth2.sdk.AccessTokenResponse; import com.nimbusds.oauth2.sdk.AccessTokenResponse;
@ -33,8 +33,8 @@ import com.nimbusds.oauth2.sdk.id.ClientID;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod; import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException; import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.core.OAuth2Error; import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
@ -49,8 +49,8 @@ import java.util.Set;
/** /**
* An implementation of an {@link AuthorizationGrantTokenExchanger} that <i>&quot;exchanges&quot;</i> * An implementation of an {@link AuthorizationGrantTokenExchanger} that <i>&quot;exchanges&quot;</i>
* an <i>authorization code</i> credential for an <i>access token</i> credential * an <i>Authorization Code</i> credential for an <i>Access Token</i> credential
* at the authorization server's <i>Token Endpoint</i>. * at the Authorization Server's <i>Token Endpoint</i>.
* *
* <p> * <p>
* <b>NOTE:</b> This implementation uses the <b>Nimbus OAuth 2.0 SDK</b> internally. * <b>NOTE:</b> This implementation uses the <b>Nimbus OAuth 2.0 SDK</b> internally.
@ -58,24 +58,24 @@ import java.util.Set;
* @author Joe Grandja * @author Joe Grandja
* @since 5.0 * @since 5.0
* @see AuthorizationGrantTokenExchanger * @see AuthorizationGrantTokenExchanger
* @see OAuth2AuthorizationCodeAuthenticationToken * @see OAuth2AuthorizationCodeGrantRequest
* @see OAuth2AccessTokenResponse * @see OAuth2AccessTokenResponse
* @see <a target="_blank" href="https://connect2id.com/products/nimbus-oauth-openid-connect-sdk">Nimbus OAuth 2.0 SDK</a> * @see <a target="_blank" href="https://connect2id.com/products/nimbus-oauth-openid-connect-sdk">Nimbus OAuth 2.0 SDK</a>
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.3">Section 4.1.3 Access Token Request (Authorization Code Grant)</a> * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.3">Section 4.1.3 Access Token Request (Authorization Code Grant)</a>
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.4">Section 4.1.4 Access Token Response (Authorization Code Grant)</a> * @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-4.1.4">Section 4.1.4 Access Token Response (Authorization Code Grant)</a>
*/ */
public class NimbusAuthorizationCodeTokenExchanger implements AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> { public class NimbusAuthorizationCodeTokenExchanger implements AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> {
private static final String INVALID_TOKEN_RESPONSE_ERROR_CODE = "invalid_token_response"; private static final String INVALID_TOKEN_RESPONSE_ERROR_CODE = "invalid_token_response";
@Override @Override
public OAuth2AccessTokenResponse exchange(OAuth2AuthorizationCodeAuthenticationToken authorizationCodeAuthentication) public OAuth2AccessTokenResponse exchange(OAuth2AuthorizationCodeGrantRequest authorizationGrantRequest)
throws OAuth2AuthenticationException { throws OAuth2AuthenticationException {
ClientRegistration clientRegistration = authorizationCodeAuthentication.getClientRegistration(); ClientRegistration clientRegistration = authorizationGrantRequest.getClientRegistration();
// Build the authorization code grant request for the token endpoint // Build the authorization code grant request for the token endpoint
AuthorizationCode authorizationCode = new AuthorizationCode( AuthorizationCode authorizationCode = new AuthorizationCode(
authorizationCodeAuthentication.getAuthorizationExchange().getAuthorizationResponse().getCode()); authorizationGrantRequest.getAuthorizationExchange().getAuthorizationResponse().getCode());
URI redirectUri = toURI(clientRegistration.getRedirectUri()); URI redirectUri = toURI(clientRegistration.getRedirectUri());
AuthorizationGrant authorizationCodeGrant = new AuthorizationCodeGrant(authorizationCode, redirectUri); AuthorizationGrant authorizationCodeGrant = new AuthorizationCodeGrant(authorizationCode, redirectUri);
URI tokenUri = toURI(clientRegistration.getProviderDetails().getTokenUri()); URI tokenUri = toURI(clientRegistration.getProviderDetails().getTokenUri());
@ -130,7 +130,7 @@ public class NimbusAuthorizationCodeTokenExchanger implements AuthorizationGrant
Set<String> scopes; Set<String> scopes;
if (CollectionUtils.isEmpty(accessTokenResponse.getTokens().getAccessToken().getScope())) { if (CollectionUtils.isEmpty(accessTokenResponse.getTokens().getAccessToken().getScope())) {
scopes = new LinkedHashSet<>( scopes = new LinkedHashSet<>(
authorizationCodeAuthentication.getAuthorizationExchange().getAuthorizationRequest().getScopes()); authorizationGrantRequest.getAuthorizationExchange().getAuthorizationRequest().getScopes());
} else { } else {
scopes = new LinkedHashSet<>( scopes = new LinkedHashSet<>(
accessTokenResponse.getTokens().getAccessToken().getScope().toStringList()); accessTokenResponse.getTokens().getAccessToken().getScope().toStringList());

View File

@ -0,0 +1,54 @@
/*
* Copyright 2002-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.oauth2.client.endpoint;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationExchange;
import org.springframework.util.Assert;
/**
* An <i>OAuth 2.0 Authorization Code Grant</i> request that holds an <i>Authorization Code</i> credential,
* which was granted by the <i>Resource Owner</i> to the specified {@link #getClientRegistration() Client}.
*
* @author Joe Grandja
* @since 5.0
* @see AbstractOAuth2AuthorizationGrantRequest
* @see ClientRegistration
* @see OAuth2AuthorizationExchange
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.3.1">Section 1.3.1 Authorization Code Grant</a>
*/
public class OAuth2AuthorizationCodeGrantRequest extends AbstractOAuth2AuthorizationGrantRequest {
private final ClientRegistration clientRegistration;
private final OAuth2AuthorizationExchange authorizationExchange;
public OAuth2AuthorizationCodeGrantRequest(ClientRegistration clientRegistration,
OAuth2AuthorizationExchange authorizationExchange) {
super(AuthorizationGrantType.AUTHORIZATION_CODE);
Assert.notNull(clientRegistration, "clientRegistration cannot be null");
Assert.notNull(authorizationExchange, "authorizationExchange cannot be null");
this.clientRegistration = clientRegistration;
this.authorizationExchange = authorizationExchange;
}
public ClientRegistration getClientRegistration() {
return this.clientRegistration;
}
public OAuth2AuthorizationExchange getAuthorizationExchange() {
return this.authorizationExchange;
}
}

View File

@ -20,9 +20,10 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper; import org.springframework.security.core.authority.mapping.GrantedAuthoritiesMapper;
import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger; import org.springframework.security.oauth2.client.endpoint.AuthorizationGrantTokenExchanger;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken; import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken;
import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.jwt.JwtDecoderRegistry; import org.springframework.security.oauth2.client.jwt.JwtDecoderRegistry;
import org.springframework.security.oauth2.client.oidc.OidcAuthorizedClient; import org.springframework.security.oauth2.client.oidc.OidcAuthorizedClient;
import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest; import org.springframework.security.oauth2.client.oidc.userinfo.OidcUserRequest;
@ -76,13 +77,13 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati
private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter"; private static final String INVALID_STATE_PARAMETER_ERROR_CODE = "invalid_state_parameter";
private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter"; private static final String INVALID_REDIRECT_URI_PARAMETER_ERROR_CODE = "invalid_redirect_uri_parameter";
private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token"; private static final String INVALID_ID_TOKEN_ERROR_CODE = "invalid_id_token";
private final AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger; private final AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger;
private final OAuth2UserService<OidcUserRequest, OidcUser> userService; private final OAuth2UserService<OidcUserRequest, OidcUser> userService;
private final JwtDecoderRegistry jwtDecoderRegistry; private final JwtDecoderRegistry jwtDecoderRegistry;
private GrantedAuthoritiesMapper authoritiesMapper = (authorities -> authorities); private GrantedAuthoritiesMapper authoritiesMapper = (authorities -> authorities);
public OidcAuthorizationCodeAuthenticationProvider( public OidcAuthorizationCodeAuthenticationProvider(
AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> authorizationCodeTokenExchanger, AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> authorizationCodeTokenExchanger,
OAuth2UserService<OidcUserRequest, OidcUser> userService, OAuth2UserService<OidcUserRequest, OidcUser> userService,
JwtDecoderRegistry jwtDecoderRegistry) { JwtDecoderRegistry jwtDecoderRegistry) {
@ -130,7 +131,10 @@ public class OidcAuthorizationCodeAuthenticationProvider implements Authenticati
} }
OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse accessTokenResponse =
this.authorizationCodeTokenExchanger.exchange(authorizationCodeAuthentication); this.authorizationCodeTokenExchanger.exchange(
new OAuth2AuthorizationCodeGrantRequest(
authorizationCodeAuthentication.getClientRegistration(),
authorizationCodeAuthentication.getAuthorizationExchange()));
OAuth2AccessToken accessToken = new OAuth2AccessToken(accessTokenResponse.getTokenType(), OAuth2AccessToken accessToken = new OAuth2AccessToken(accessTokenResponse.getTokenType(),
accessTokenResponse.getTokenValue(), accessTokenResponse.getIssuedAt(), accessTokenResponse.getTokenValue(), accessTokenResponse.getIssuedAt(),

View File

@ -36,17 +36,17 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthorizationCodeAuthenticationToken; import org.springframework.security.oauth2.client.endpoint.AuthorizationGrantTokenExchanger;
import org.springframework.security.oauth2.client.authentication.AuthorizationGrantTokenExchanger; import org.springframework.security.oauth2.client.endpoint.OAuth2AuthorizationCodeGrantRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository; import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter; import org.springframework.security.oauth2.client.web.OAuth2AuthorizationRequestRedirectFilter;
import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter; import org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter;
import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AccessTokenResponse;
import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationResponseType;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User; import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2UserAuthority; import org.springframework.security.oauth2.core.user.OAuth2UserAuthority;
import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.junit4.SpringRunner;
@ -354,7 +354,7 @@ public class OAuth2LoginApplicationTests {
} }
// @formatter:on // @formatter:on
private AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeAuthenticationToken> mockAuthorizationCodeTokenExchanger() { private AuthorizationGrantTokenExchanger<OAuth2AuthorizationCodeGrantRequest> mockAuthorizationCodeTokenExchanger() {
OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("access-token-1234") OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("access-token-1234")
.tokenType(OAuth2AccessToken.TokenType.BEARER) .tokenType(OAuth2AccessToken.TokenType.BEARER)
.expiresIn(60 * 1000) .expiresIn(60 * 1000)