Introduce base Authentication for authorization grant

Closes gh-216
This commit is contained in:
Joe Grandja 2021-02-05 06:30:12 -05:00
parent 1fa0161164
commit 218d49b134
15 changed files with 179 additions and 320 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,15 +15,13 @@
*/
package org.springframework.security.oauth2.server.authorization.authentication;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.authorization.Version;
import org.springframework.util.Assert;
import java.util.Collections;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.util.Assert;
/**
* An {@link Authentication} implementation used for the OAuth 2.0 Authorization Code Grant.
*
@ -31,16 +29,12 @@ import java.util.Map;
* @author Madhu Bhat
* @author Daniel Garnier-Moiroux
* @since 0.0.1
* @see AbstractAuthenticationToken
* @see OAuth2AuthorizationGrantAuthenticationToken
* @see OAuth2AuthorizationCodeAuthenticationProvider
* @see OAuth2ClientAuthenticationToken
*/
public class OAuth2AuthorizationCodeAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
public class OAuth2AuthorizationCodeAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
private final String code;
private final Authentication clientPrincipal;
private final String redirectUri;
private final Map<String, Object> additionalParameters;
/**
* Constructs an {@code OAuth2AuthorizationCodeAuthenticationToken} using the provided parameters.
@ -52,26 +46,10 @@ public class OAuth2AuthorizationCodeAuthenticationToken extends AbstractAuthenti
*/
public OAuth2AuthorizationCodeAuthenticationToken(String code, Authentication clientPrincipal,
@Nullable String redirectUri, @Nullable Map<String, Object> additionalParameters) {
super(Collections.emptyList());
super(AuthorizationGrantType.AUTHORIZATION_CODE, clientPrincipal, additionalParameters);
Assert.hasText(code, "code cannot be empty");
Assert.notNull(clientPrincipal, "clientPrincipal cannot be null");
this.code = code;
this.clientPrincipal = clientPrincipal;
this.redirectUri = redirectUri;
this.additionalParameters = Collections.unmodifiableMap(
additionalParameters != null ?
additionalParameters :
Collections.emptyMap());
}
@Override
public Object getPrincipal() {
return this.clientPrincipal;
}
@Override
public Object getCredentials() {
return "";
}
/**
@ -88,16 +66,8 @@ public class OAuth2AuthorizationCodeAuthenticationToken extends AbstractAuthenti
*
* @return the redirect uri
*/
public @Nullable String getRedirectUri() {
@Nullable
public String getRedirectUri() {
return this.redirectUri;
}
/**
* Returns the additional parameters
*
* @return the additional parameters
*/
public Map<String, Object> getAdditionalParameters() {
return this.additionalParameters;
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2020-2021 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 org.springframework.security.oauth2.server.authorization.authentication;
import java.util.Collections;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.server.authorization.Version;
import org.springframework.util.Assert;
/**
* Base implementation of an {@link Authentication} representing an OAuth 2.0 Authorization Grant.
*
* @author Joe Grandja
* @since 0.1.0
* @see AbstractAuthenticationToken
* @see AuthorizationGrantType
* @see OAuth2ClientAuthenticationToken
* @see <a target="_blank" href="https://tools.ietf.org/html/rfc6749#section-1.3">Section 1.3 Authorization Grant</a>
*/
public class OAuth2AuthorizationGrantAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
private final AuthorizationGrantType authorizationGrantType;
private final Authentication clientPrincipal;
private final Map<String, Object> additionalParameters;
/**
* Sub-class constructor.
*
* @param authorizationGrantType the authorization grant type
* @param clientPrincipal the authenticated client principal
* @param additionalParameters the additional parameters
*/
protected OAuth2AuthorizationGrantAuthenticationToken(AuthorizationGrantType authorizationGrantType,
Authentication clientPrincipal, @Nullable Map<String, Object> additionalParameters) {
super(Collections.emptyList());
Assert.notNull(authorizationGrantType, "authorizationGrantType cannot be null");
Assert.notNull(clientPrincipal, "clientPrincipal cannot be null");
this.authorizationGrantType = authorizationGrantType;
this.clientPrincipal = clientPrincipal;
this.additionalParameters = Collections.unmodifiableMap(
additionalParameters != null ?
additionalParameters :
Collections.emptyMap());
}
/**
* Returns the authorization grant type.
*
* @return the authorization grant type
*/
public AuthorizationGrantType getGrantType() {
return this.authorizationGrantType;
}
@Override
public Object getPrincipal() {
return this.clientPrincipal;
}
@Override
public Object getCredentials() {
return "";
}
/**
* Returns the additional parameters.
*
* @return the additional parameters
*/
public Map<String, Object> getAdditionalParameters() {
return this.additionalParameters;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,27 +15,23 @@
*/
package org.springframework.security.oauth2.server.authorization.authentication;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.authorization.Version;
import org.springframework.util.Assert;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.util.Assert;
/**
* An {@link Authentication} implementation used for the OAuth 2.0 Client Credentials Grant.
*
* @author Alexey Nesterov
* @since 0.0.1
* @see AbstractAuthenticationToken
* @see OAuth2AuthorizationGrantAuthenticationToken
* @see OAuth2ClientCredentialsAuthenticationProvider
* @see OAuth2ClientAuthenticationToken
*/
public class OAuth2ClientCredentialsAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
private final Authentication clientPrincipal;
public class OAuth2ClientCredentialsAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
private final Set<String> scopes;
/**
@ -54,23 +50,11 @@ public class OAuth2ClientCredentialsAuthenticationToken extends AbstractAuthenti
* @param scopes the requested scope(s)
*/
public OAuth2ClientCredentialsAuthenticationToken(Authentication clientPrincipal, Set<String> scopes) {
super(Collections.emptyList());
Assert.notNull(clientPrincipal, "clientPrincipal cannot be null");
super(AuthorizationGrantType.CLIENT_CREDENTIALS, clientPrincipal, null);
Assert.notNull(scopes, "scopes cannot be null");
this.clientPrincipal = clientPrincipal;
this.scopes = Collections.unmodifiableSet(new LinkedHashSet<>(scopes));
}
@Override
public Object getPrincipal() {
return this.clientPrincipal;
}
@Override
public Object getCredentials() {
return "";
}
/**
* Returns the requested scope(s).
*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,27 +15,23 @@
*/
package org.springframework.security.oauth2.server.authorization.authentication;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.authorization.Version;
import org.springframework.util.Assert;
import java.util.Collections;
import java.util.Set;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.util.Assert;
/**
* An {@link Authentication} implementation used for the OAuth 2.0 Refresh Token Grant.
*
* @author Alexey Nesterov
* @since 0.0.3
* @see AbstractAuthenticationToken
* @see OAuth2AuthorizationGrantAuthenticationToken
* @see OAuth2RefreshTokenAuthenticationProvider
* @see OAuth2ClientAuthenticationToken
*/
public class OAuth2RefreshTokenAuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = Version.SERIAL_VERSION_UID;
public class OAuth2RefreshTokenAuthenticationToken extends OAuth2AuthorizationGrantAuthenticationToken {
private final String refreshToken;
private final Authentication clientPrincipal;
private final Set<String> scopes;
/**
@ -57,25 +53,13 @@ public class OAuth2RefreshTokenAuthenticationToken extends AbstractAuthenticatio
*/
public OAuth2RefreshTokenAuthenticationToken(String refreshToken, Authentication clientPrincipal,
Set<String> scopes) {
super(Collections.emptySet());
super(AuthorizationGrantType.REFRESH_TOKEN, clientPrincipal, null);
Assert.hasText(refreshToken, "refreshToken cannot be empty");
Assert.notNull(clientPrincipal, "clientPrincipal cannot be null");
Assert.notNull(scopes, "scopes cannot be null");
this.refreshToken = refreshToken;
this.clientPrincipal = clientPrincipal;
this.scopes = scopes;
}
@Override
public Object getPrincipal() {
return this.clientPrincipal;
}
@Override
public Object getCredentials() {
return "";
}
/**
* Returns the refresh token.
*

View File

@ -25,6 +25,7 @@ import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.context.Context;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.TokenType;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.util.Assert;
@ -56,7 +57,7 @@ public interface OAuth2TokenContext extends Context {
return get(AuthorizationGrantType.class);
}
default <T extends Authentication> T getAuthorizationGrant() {
default <T extends OAuth2AuthorizationGrantAuthenticationToken> T getAuthorizationGrant() {
return get(AbstractBuilder.AUTHORIZATION_GRANT_AUTHENTICATION_KEY);
}
@ -87,7 +88,7 @@ public interface OAuth2TokenContext extends Context {
return put(AuthorizationGrantType.class, authorizationGrantType);
}
public B authorizationGrant(Authentication authorizationGrant) {
public B authorizationGrant(OAuth2AuthorizationGrantAuthenticationToken authorizationGrant) {
return put(AUTHORIZATION_GRANT_AUTHENTICATION_KEY, authorizationGrant);
}

View File

@ -1,70 +0,0 @@
/*
* Copyright 2020 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 org.springframework.security.oauth2.server.authorization.web;
import org.springframework.core.convert.converter.Converter;
import org.springframework.lang.Nullable;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* A {@link Converter} that selects (and delegates) to one of the internal {@code Map} of {@link Converter}'s
* using the {@link OAuth2ParameterNames#GRANT_TYPE} request parameter.
*
* @author Alexey Nesterov
* @since 0.0.1
*/
public final class DelegatingAuthorizationGrantAuthenticationConverter implements Converter<HttpServletRequest, Authentication> {
private final Map<AuthorizationGrantType, Converter<HttpServletRequest, Authentication>> converters;
/**
* Constructs a {@code DelegatingAuthorizationGrantAuthenticationConverter} using the provided parameters.
*
* @param converters a {@code Map} of {@link Converter}(s)
*/
public DelegatingAuthorizationGrantAuthenticationConverter(
Map<AuthorizationGrantType, Converter<HttpServletRequest, Authentication>> converters) {
Assert.notEmpty(converters, "converters cannot be empty");
this.converters = Collections.unmodifiableMap(new HashMap<>(converters));
}
@Nullable
@Override
public Authentication convert(HttpServletRequest request) {
Assert.notNull(request, "request cannot be null");
String grantType = request.getParameter(OAuth2ParameterNames.GRANT_TYPE);
if (StringUtils.isEmpty(grantType)) {
return null;
}
Converter<HttpServletRequest, Authentication> converter =
this.converters.get(new AuthorizationGrantType(grantType));
if (converter == null) {
return null;
}
return converter.convert(request);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,7 +15,21 @@
*/
package org.springframework.security.oauth2.server.authorization.web;
import org.springframework.core.convert.converter.Converter;
import java.io.IOException;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
@ -40,6 +54,7 @@ import org.springframework.security.oauth2.server.authorization.authentication.O
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationProvider;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2RefreshTokenAuthenticationToken;
import org.springframework.security.web.authentication.AuthenticationConverter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.util.Assert;
@ -48,19 +63,6 @@ import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.temporal.ChronoUnit;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* A {@code Filter} for the OAuth 2.0 Token endpoint,
* which handles the processing of an OAuth 2.0 Authorization Grant.
@ -98,7 +100,7 @@ public class OAuth2TokenEndpointFilter extends OncePerRequestFilter {
private final AuthenticationManager authenticationManager;
private final RequestMatcher tokenEndpointMatcher;
private final Converter<HttpServletRequest, Authentication> authorizationGrantAuthenticationConverter;
private final AuthenticationConverter authorizationGrantAuthenticationConverter;
private final HttpMessageConverter<OAuth2AccessTokenResponse> accessTokenHttpResponseConverter =
new OAuth2AccessTokenResponseHttpMessageConverter();
private final HttpMessageConverter<OAuth2Error> errorHttpResponseConverter =
@ -124,11 +126,11 @@ public class OAuth2TokenEndpointFilter extends OncePerRequestFilter {
Assert.hasText(tokenEndpointUri, "tokenEndpointUri cannot be empty");
this.authenticationManager = authenticationManager;
this.tokenEndpointMatcher = new AntPathRequestMatcher(tokenEndpointUri, HttpMethod.POST.name());
Map<AuthorizationGrantType, Converter<HttpServletRequest, Authentication>> converters = new HashMap<>();
converters.put(AuthorizationGrantType.AUTHORIZATION_CODE, new AuthorizationCodeAuthenticationConverter());
converters.put(AuthorizationGrantType.REFRESH_TOKEN, new RefreshTokenAuthenticationConverter());
converters.put(AuthorizationGrantType.CLIENT_CREDENTIALS, new ClientCredentialsAuthenticationConverter());
this.authorizationGrantAuthenticationConverter = new DelegatingAuthorizationGrantAuthenticationConverter(converters);
List<AuthenticationConverter> converters = new ArrayList<>();
converters.add(new AuthorizationCodeAuthenticationConverter());
converters.add(new RefreshTokenAuthenticationConverter());
converters.add(new ClientCredentialsAuthenticationConverter());
this.authorizationGrantAuthenticationConverter = new DelegatingAuthenticationConverter(converters);
}
@Override
@ -198,7 +200,7 @@ public class OAuth2TokenEndpointFilter extends OncePerRequestFilter {
throw new OAuth2AuthenticationException(error);
}
private static class AuthorizationCodeAuthenticationConverter implements Converter<HttpServletRequest, Authentication> {
private static class AuthorizationCodeAuthenticationConverter implements AuthenticationConverter {
@Override
public Authentication convert(HttpServletRequest request) {
@ -240,7 +242,7 @@ public class OAuth2TokenEndpointFilter extends OncePerRequestFilter {
}
}
private static class RefreshTokenAuthenticationConverter implements Converter<HttpServletRequest, Authentication> {
private static class RefreshTokenAuthenticationConverter implements AuthenticationConverter {
@Override
public Authentication convert(HttpServletRequest request) {
@ -277,7 +279,7 @@ public class OAuth2TokenEndpointFilter extends OncePerRequestFilter {
}
}
private static class ClientCredentialsAuthenticationConverter implements Converter<HttpServletRequest, Authentication> {
private static class ClientCredentialsAuthenticationConverter implements AuthenticationConverter {
@Override
public Authentication convert(HttpServletRequest request) {

View File

@ -40,7 +40,6 @@ import org.springframework.security.oauth2.jwt.JoseHeaderNames;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationAttributeNames;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
@ -48,6 +47,7 @@ import org.springframework.security.oauth2.server.authorization.TestOAuth2Author
import org.springframework.security.oauth2.server.authorization.TokenType;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2AuthorizationCode;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenMetadata;
@ -247,7 +247,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
assertThat(jwtEncodingContext.getTokenType()).isEqualTo(TokenType.ACCESS_TOKEN);
assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(jwtEncodingContext.<Authentication>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.getHeaders()).isNotNull();
assertThat(jwtEncodingContext.getClaims()).isNotNull();
@ -299,7 +299,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
assertThat(accessTokenContext.getAuthorization()).isEqualTo(authorization);
assertThat(accessTokenContext.getTokenType()).isEqualTo(TokenType.ACCESS_TOKEN);
assertThat(accessTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(accessTokenContext.<Authentication>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(accessTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(accessTokenContext.getHeaders()).isNotNull();
assertThat(accessTokenContext.getClaims()).isNotNull();
// ID Token context
@ -309,7 +309,7 @@ public class OAuth2AuthorizationCodeAuthenticationProviderTests {
assertThat(idTokenContext.getAuthorization()).isEqualTo(authorization);
assertThat(idTokenContext.getTokenType().getValue()).isEqualTo(OidcParameterNames.ID_TOKEN);
assertThat(idTokenContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(idTokenContext.<Authentication>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(idTokenContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(idTokenContext.getHeaders()).isNotNull();
assertThat(idTokenContext.getClaims()).isNotNull();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,12 +15,14 @@
*/
package org.springframework.security.oauth2.server.authorization.authentication;
import org.junit.Test;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import java.util.Collections;
import java.util.Map;
import org.junit.Test;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ -55,6 +57,7 @@ public class OAuth2AuthorizationCodeAuthenticationTokenTests {
public void constructorWhenClientPrincipalProvidedThenCreated() {
OAuth2AuthorizationCodeAuthenticationToken authentication = new OAuth2AuthorizationCodeAuthenticationToken(
this.code, this.clientPrincipal, this.redirectUri, this.additionalParameters);
assertThat(authentication.getGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(authentication.getPrincipal()).isEqualTo(this.clientPrincipal);
assertThat(authentication.getCredentials().toString()).isEmpty();
assertThat(authentication.getCode()).isEqualTo(this.code);

View File

@ -35,12 +35,12 @@ import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.jwt.JoseHeaderNames;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
import org.springframework.security.oauth2.server.authorization.TokenType;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import static org.assertj.core.api.Assertions.assertThat;
@ -194,7 +194,7 @@ public class OAuth2ClientCredentialsAuthenticationProviderTests {
assertThat(jwtEncodingContext.getAuthorization()).isNull();
assertThat(jwtEncodingContext.getTokenType()).isEqualTo(TokenType.ACCESS_TOKEN);
assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
assertThat(jwtEncodingContext.<Authentication>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.getHeaders()).isNotNull();
assertThat(jwtEncodingContext.getClaims()).isNotNull();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,12 +15,14 @@
*/
package org.springframework.security.oauth2.server.authorization.authentication;
import org.junit.Test;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import java.util.Collections;
import java.util.Set;
import org.junit.Test;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ -52,6 +54,7 @@ public class OAuth2ClientCredentialsAuthenticationTokenTests {
OAuth2ClientCredentialsAuthenticationToken authentication =
new OAuth2ClientCredentialsAuthenticationToken(this.clientPrincipal);
assertThat(authentication.getGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
assertThat(authentication.getPrincipal()).isEqualTo(this.clientPrincipal);
assertThat(authentication.getCredentials().toString()).isEmpty();
assertThat(authentication.getScopes()).isEmpty();
@ -64,6 +67,7 @@ public class OAuth2ClientCredentialsAuthenticationTokenTests {
OAuth2ClientCredentialsAuthenticationToken authentication =
new OAuth2ClientCredentialsAuthenticationToken(this.clientPrincipal, expectedScopes);
assertThat(authentication.getGrantType()).isEqualTo(AuthorizationGrantType.CLIENT_CREDENTIALS);
assertThat(authentication.getPrincipal()).isEqualTo(this.clientPrincipal);
assertThat(authentication.getCredentials().toString()).isEmpty();
assertThat(authentication.getScopes()).isEqualTo(expectedScopes);

View File

@ -38,7 +38,6 @@ import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
import org.springframework.security.oauth2.jwt.JoseHeaderNames;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtEncoder;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationAttributeNames;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
@ -46,6 +45,7 @@ import org.springframework.security.oauth2.server.authorization.TestOAuth2Author
import org.springframework.security.oauth2.server.authorization.TokenType;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import org.springframework.security.oauth2.server.authorization.token.JwtEncodingContext;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenCustomizer;
import org.springframework.security.oauth2.server.authorization.token.OAuth2TokenMetadata;
import org.springframework.security.oauth2.server.authorization.token.OAuth2Tokens;
@ -139,7 +139,7 @@ public class OAuth2RefreshTokenAuthenticationProviderTests {
assertThat(jwtEncodingContext.getAuthorization()).isEqualTo(authorization);
assertThat(jwtEncodingContext.getTokenType()).isEqualTo(TokenType.ACCESS_TOKEN);
assertThat(jwtEncodingContext.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
assertThat(jwtEncodingContext.<Authentication>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authentication);
assertThat(jwtEncodingContext.getHeaders()).isNotNull();
assertThat(jwtEncodingContext.getClaims()).isNotNull();

View File

@ -1,5 +1,5 @@
/*
* Copyright 2020 the original author or authors.
* Copyright 2020-2021 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.
@ -15,13 +15,15 @@
*/
package org.springframework.security.oauth2.server.authorization.authentication;
import org.junit.Test;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.junit.Test;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ -64,6 +66,7 @@ public class OAuth2RefreshTokenAuthenticationTokenTests {
Set<String> expectedScopes = new HashSet<>(Arrays.asList("scope-a", "scope-b"));
OAuth2RefreshTokenAuthenticationToken authentication = new OAuth2RefreshTokenAuthenticationToken(
"refresh-token", this.clientPrincipal, expectedScopes);
assertThat(authentication.getGrantType()).isEqualTo(AuthorizationGrantType.REFRESH_TOKEN);
assertThat(authentication.getRefreshToken()).isEqualTo("refresh-token");
assertThat(authentication.getPrincipal()).isEqualTo(this.clientPrincipal);
assertThat(authentication.getCredentials().toString()).isEmpty();

View File

@ -30,6 +30,7 @@ import org.springframework.security.oauth2.server.authorization.OAuth2Authorizat
import org.springframework.security.oauth2.server.authorization.TestOAuth2Authorizations;
import org.springframework.security.oauth2.server.authorization.TokenType;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationCodeAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2AuthorizationGrantAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.RegisteredClient;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
@ -110,7 +111,7 @@ public class JwtEncodingContextTests {
assertThat(context.getAuthorization()).isEqualTo(authorization);
assertThat(context.getTokenType()).isEqualTo(TokenType.ACCESS_TOKEN);
assertThat(context.getAuthorizationGrantType()).isEqualTo(AuthorizationGrantType.AUTHORIZATION_CODE);
assertThat(context.<Authentication>getAuthorizationGrant()).isEqualTo(authorizationGrant);
assertThat(context.<OAuth2AuthorizationGrantAuthenticationToken>getAuthorizationGrant()).isEqualTo(authorizationGrant);
assertThat(context.<String>get("custom-key-1")).isEqualTo("custom-value-1");
assertThat(context.<String>get("custom-key-2")).isEqualTo("custom-value-2");
}

View File

@ -1,114 +0,0 @@
/*
* Copyright 2020 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 org.springframework.security.oauth2.server.authorization.web;
import org.junit.Before;
import org.junit.Test;
import org.springframework.core.convert.converter.Converter;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockServletContext;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.authentication.OAuth2ClientCredentialsAuthenticationToken;
import org.springframework.security.oauth2.server.authorization.client.TestRegisteredClients;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
/**
* Tests for {@link DelegatingAuthorizationGrantAuthenticationConverter}.
*
* @author Alexey Nesterov
*/
public class DelegatingAuthorizationGrantAuthenticationConverterTests {
private Converter<HttpServletRequest, Authentication> clientCredentialsAuthenticationConverter;
private DelegatingAuthorizationGrantAuthenticationConverter authenticationConverter;
@Before
public void setUp() {
this.clientCredentialsAuthenticationConverter = mock(Converter.class);
Map<AuthorizationGrantType, Converter<HttpServletRequest, Authentication>> converters =
Collections.singletonMap(AuthorizationGrantType.CLIENT_CREDENTIALS, this.clientCredentialsAuthenticationConverter);
this.authenticationConverter = new DelegatingAuthorizationGrantAuthenticationConverter(converters);
}
@Test
public void constructorWhenConvertersEmptyThenThrowIllegalArgumentException() {
assertThatThrownBy(() -> new DelegatingAuthorizationGrantAuthenticationConverter(Collections.emptyMap()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("converters cannot be empty");
}
@Test
public void convertWhenRequestNullThenThrowIllegalArgumentException() {
assertThatThrownBy(() -> this.authenticationConverter.convert(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("request cannot be null");
}
@Test
public void convertWhenGrantTypeMissingThenNull() {
MockHttpServletRequest request = MockMvcRequestBuilders
.post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.buildRequest(new MockServletContext());
Authentication authentication = this.authenticationConverter.convert(request);
assertThat(authentication).isNull();
verifyNoInteractions(this.clientCredentialsAuthenticationConverter);
}
@Test
public void convertWhenGrantTypeUnsupportedThenNull() {
MockHttpServletRequest request = MockMvcRequestBuilders
.post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.param(OAuth2ParameterNames.GRANT_TYPE, "extension_grant_type")
.buildRequest(new MockServletContext());
Authentication authentication = this.authenticationConverter.convert(request);
assertThat(authentication).isNull();
verifyNoInteractions(this.clientCredentialsAuthenticationConverter);
}
@Test
public void convertWhenGrantTypeSupportedThenConverterCalled() {
OAuth2ClientCredentialsAuthenticationToken expectedAuthentication =
new OAuth2ClientCredentialsAuthenticationToken(
new OAuth2ClientAuthenticationToken(
TestRegisteredClients.registeredClient().build()));
when(this.clientCredentialsAuthenticationConverter.convert(any())).thenReturn(expectedAuthentication);
MockHttpServletRequest request = MockMvcRequestBuilders
.post(OAuth2TokenEndpointFilter.DEFAULT_TOKEN_ENDPOINT_URI)
.param(OAuth2ParameterNames.GRANT_TYPE, AuthorizationGrantType.CLIENT_CREDENTIALS.getValue())
.buildRequest(new MockServletContext());
Authentication authentication = this.authenticationConverter.convert(request);
assertThat(authentication).isEqualTo(expectedAuthentication);
verify(this.clientCredentialsAuthenticationConverter).convert(request);
}
}