diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizedClient.java similarity index 61% rename from oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java rename to oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizedClient.java index 88b26c7ef4..2c793584a9 100644 --- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2ClientAuthenticationToken.java +++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizedClient.java @@ -15,26 +15,22 @@ */ package org.springframework.security.oauth2.client.authentication; -import org.springframework.security.authentication.AbstractAuthenticationToken; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.SpringSecurityCoreVersion; import org.springframework.security.oauth2.client.registration.ClientRegistration; import org.springframework.security.oauth2.core.AccessToken; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; -import java.util.Collections; import java.util.Set; /** - * An implementation of an {@link AbstractAuthenticationToken} - * that represents an OAuth 2.0 Client {@link Authentication}. - * + * A representation of an OAuth 2.0 "Authorized Client". *
- * A client is considered "authenticated", - * if it receives a successful response from the Token Endpoint. - * This {@link Authentication} associates the client identified in {@link #getClientRegistration()} - * to the {@link #getAccessToken()} granted by the resource owner. + * A client is considered "authorized" + * when it receives a successful response from the Token Endpoint. + *
+ * This class associates the {@link #getClientRegistration() Client}
+ * to the {@link #getAccessToken() Access Token}
+ * granted/authorized by the {@link #getPrincipalName() Resource Owner}.
*
* @author Joe Grandja
* @since 5.0
@@ -42,34 +38,28 @@ import java.util.Set;
* @see AccessToken
* @see Section 5.1 Access Token Response
*/
-public class OAuth2ClientAuthenticationToken extends AbstractAuthenticationToken {
- private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
+public class AuthorizedClient {
private final ClientRegistration clientRegistration;
+ private final String principalName;
private final AccessToken accessToken;
- public OAuth2ClientAuthenticationToken(ClientRegistration clientRegistration, AccessToken accessToken) {
- super(Collections.emptyList());
+ public AuthorizedClient(ClientRegistration clientRegistration, String principalName, AccessToken accessToken) {
Assert.notNull(clientRegistration, "clientRegistration cannot be null");
+ Assert.hasText(principalName, "principalName cannot be empty");
Assert.notNull(accessToken, "accessToken cannot be null");
this.clientRegistration = clientRegistration;
+ this.principalName = principalName;
this.accessToken = accessToken;
- this.setAuthenticated(true); // The Client is authenticated by the Authorization Server
- }
-
- @Override
- public Object getPrincipal() {
- return this.getClientRegistration().getClientId();
- }
-
- @Override
- public Object getCredentials() {
- return ""; // No need to expose this.getClientRegistration().getClientSecret()
}
public ClientRegistration getClientRegistration() {
return this.clientRegistration;
}
+ public String getPrincipalName() {
+ return this.principalName;
+ }
+
public AccessToken getAccessToken() {
return this.accessToken;
}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2LoginAuthenticationProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2LoginAuthenticationProvider.java
index bd5098c976..958d574c27 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2LoginAuthenticationProvider.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/OAuth2LoginAuthenticationProvider.java
@@ -51,7 +51,7 @@ import java.util.Collection;
* @see AuthorizationCodeAuthenticationToken
* @see SecurityTokenRepository
* @see OAuth2AuthenticationToken
- * @see OAuth2ClientAuthenticationToken
+ * @see AuthorizedClient
* @see OAuth2UserService
* @see OAuth2User
* @see Section 4.1 Authorization Code Grant Flow
@@ -118,22 +118,25 @@ public class OAuth2LoginAuthenticationProvider implements AuthenticationProvider
tokenResponse.getTokenValue(), tokenResponse.getIssuedAt(),
tokenResponse.getExpiresAt(), tokenResponse.getScopes());
- OAuth2ClientAuthenticationToken clientAuthentication =
- new OAuth2ClientAuthenticationToken(authorizationCodeAuthentication.getClientRegistration(), accessToken);
- clientAuthentication.setDetails(authorizationCodeAuthentication.getDetails());
+ AuthorizedClient authorizedClient = new AuthorizedClient(
+ authorizationCodeAuthentication.getClientRegistration(), "unknown", accessToken);
this.accessTokenRepository.saveSecurityToken(
- clientAuthentication.getAccessToken(),
- clientAuthentication.getClientRegistration());
+ authorizedClient.getAccessToken(),
+ authorizedClient.getClientRegistration());
- OAuth2User oauth2User = this.userService.loadUser(clientAuthentication);
+ OAuth2User oauth2User = this.userService.loadUser(authorizedClient);
+
+ // Update AuthorizedClient now that we know the 'principalName'
+ authorizedClient = new AuthorizedClient(
+ authorizationCodeAuthentication.getClientRegistration(), oauth2User.getName(), accessToken);
Collection extends GrantedAuthority> mappedAuthorities =
this.authoritiesMapper.mapAuthorities(oauth2User.getAuthorities());
OAuth2AuthenticationToken authenticationResult = new OAuth2AuthenticationToken(
- oauth2User, mappedAuthorities, clientAuthentication);
- authenticationResult.setDetails(clientAuthentication.getDetails());
+ oauth2User, mappedAuthorities, authorizedClient);
+ authenticationResult.setDetails(authorizationCodeAuthentication.getDetails());
return authenticationResult;
}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/CustomUserTypesOAuth2UserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/CustomUserTypesOAuth2UserService.java
index 4acf97bc1a..c23c041a4d 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/CustomUserTypesOAuth2UserService.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/CustomUserTypesOAuth2UserService.java
@@ -15,10 +15,8 @@
*/
package org.springframework.security.oauth2.client.authentication.userinfo;
-import org.springframework.beans.BeanWrapper;
-import org.springframework.beans.PropertyAccessorFactory;
+import org.springframework.security.oauth2.client.authentication.AuthorizedClient;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.client.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
import org.springframework.util.Assert;
@@ -53,14 +51,14 @@ public class CustomUserTypesOAuth2UserService implements OAuth2UserService {
}
@Override
- public OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
- URI userInfoUri = URI.create(clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
+ public OAuth2User loadUser(AuthorizedClient authorizedClient) throws OAuth2AuthenticationException {
+ URI userInfoUri = URI.create(authorizedClient.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUri());
Class extends OAuth2User> customUserType;
if ((customUserType = this.customUserTypes.get(userInfoUri)) == null) {
return null;
}
- return this.userInfoRetriever.retrieve(clientAuthentication, customUserType);
+ return this.userInfoRetriever.retrieve(authorizedClient, customUserType);
}
public final void setUserInfoRetriever(UserInfoRetriever userInfoRetriever) {
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/DefaultOAuth2UserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/DefaultOAuth2UserService.java
index 5b25eb7b43..3c074858cb 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/DefaultOAuth2UserService.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/DefaultOAuth2UserService.java
@@ -17,7 +17,7 @@ package org.springframework.security.oauth2.client.authentication.userinfo;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.client.authentication.OAuth2ClientAuthenticationToken;
+import org.springframework.security.oauth2.client.authentication.AuthorizedClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.user.DefaultOAuth2User;
import org.springframework.security.oauth2.core.user.OAuth2User;
@@ -52,15 +52,15 @@ public class DefaultOAuth2UserService implements OAuth2UserService {
private UserInfoRetriever userInfoRetriever = new NimbusUserInfoRetriever();
@Override
- public OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
- String userNameAttributeName = clientAuthentication.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
+ public OAuth2User loadUser(AuthorizedClient authorizedClient) throws OAuth2AuthenticationException {
+ String userNameAttributeName = authorizedClient.getClientRegistration().getProviderDetails().getUserInfoEndpoint().getUserNameAttributeName();
if (!StringUtils.hasText(userNameAttributeName)) {
throw new IllegalArgumentException(
"Missing required \"user name\" attribute name in UserInfoEndpoint for Client Registration: " +
- clientAuthentication.getClientRegistration().getRegistrationId());
+ authorizedClient.getClientRegistration().getRegistrationId());
}
- Map
* Each {@link OAuth2UserService} is given a chance to
- * {@link OAuth2UserService#loadUser(OAuth2ClientAuthenticationToken) load} an {@link OAuth2User}
+ * {@link OAuth2UserService#loadUser(AuthorizedClient) load} an {@link OAuth2User}
* with the first
- * This {@link Authentication} associates an {@link OAuth2User} principal to an
- * {@link OAuth2ClientAuthenticationToken} which represents the "Authorized Client".
+ * This {@link Authentication} associates an {@link OAuth2User} principal
+ * to an {@link AuthorizedClient}.
*
* @author Joe Grandja
* @since 5.0
* @see OAuth2User
- * @see OAuth2ClientAuthenticationToken
+ * @see AuthorizedClient
*/
public class OAuth2AuthenticationToken extends AbstractAuthenticationToken {
private static final long serialVersionUID = SpringSecurityCoreVersion.SERIAL_VERSION_UID;
private final OAuth2User principal;
- private final OAuth2ClientAuthenticationToken clientAuthentication;
+ private final AuthorizedClient authorizedClient;
public OAuth2AuthenticationToken(OAuth2User principal, Collection extends GrantedAuthority> authorities,
- OAuth2ClientAuthenticationToken clientAuthentication) {
+ AuthorizedClient authorizedClient) {
super(authorities);
- Assert.notNull(clientAuthentication, "clientAuthentication cannot be null");
+ Assert.notNull(principal, "principal cannot be null");
+ Assert.notNull(authorizedClient, "authorizedClient cannot be null");
this.principal = principal;
- this.clientAuthentication = clientAuthentication;
- this.setAuthenticated(principal != null);
+ this.authorizedClient = authorizedClient;
+ this.setAuthenticated(true);
}
@Override
@@ -63,7 +63,7 @@ public class OAuth2AuthenticationToken extends AbstractAuthenticationToken {
return "";
}
- public OAuth2ClientAuthenticationToken getClientAuthentication() {
- return this.clientAuthentication;
+ public AuthorizedClient getAuthorizedClient() {
+ return this.authorizedClient;
}
}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/OAuth2UserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/OAuth2UserService.java
index e9e0ee4531..2a040eecb9 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/OAuth2UserService.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/OAuth2UserService.java
@@ -16,24 +16,24 @@
package org.springframework.security.oauth2.client.authentication.userinfo;
import org.springframework.security.core.AuthenticatedPrincipal;
+import org.springframework.security.oauth2.client.authentication.AuthorizedClient;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.client.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.core.user.OAuth2User;
/**
* Implementations of this interface are responsible for obtaining the user attributes
* of the End-User (resource owner) from the UserInfo Endpoint
- * using the provided {@link OAuth2ClientAuthenticationToken#getAccessToken()}
+ * using the provided {@link AuthorizedClient#getAccessToken()}
* and returning an {@link AuthenticatedPrincipal} in the form of an {@link OAuth2User}.
*
* @author Joe Grandja
* @since 5.0
- * @see OAuth2ClientAuthenticationToken
+ * @see AuthorizedClient
* @see AuthenticatedPrincipal
* @see OAuth2User
*/
public interface OAuth2UserService {
- OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException;
+ OAuth2User loadUser(AuthorizedClient authorizedClient) throws OAuth2AuthenticationException;
}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/UserInfoRetriever.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/UserInfoRetriever.java
index cdfecaf452..fdcfdbd09d 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/UserInfoRetriever.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/UserInfoRetriever.java
@@ -15,23 +15,22 @@
*/
package org.springframework.security.oauth2.client.authentication.userinfo;
-import org.springframework.core.ParameterizedTypeReference;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.client.authentication.OAuth2ClientAuthenticationToken;
+import org.springframework.security.oauth2.client.authentication.AuthorizedClient;
/**
* A strategy for retrieving the user attributes
* of the End-User (resource owner) from the UserInfo Endpoint
- * using the provided {@link OAuth2ClientAuthenticationToken#getAccessToken()}.
+ * using the provided {@link AuthorizedClient#getAccessToken()}.
*
* @author Joe Grandja
* @author Rob Winch
* @since 5.0
- * @see OAuth2ClientAuthenticationToken
+ * @see AuthorizedClient
* @see OAuth2UserService
*/
public interface UserInfoRetriever {
-
- * A client is considered "authenticated",
- * if it receives a successful response from the Token Endpoint.
- * This {@link Authentication} associates the client identified in {@link #getClientRegistration()}
- * to the {@link #getAccessToken()} granted by the resource owner along with the {@link #getIdToken()}
- * containing Claims about the authentication of the End-User.
+ * A client is considered "authorized"
+ * when it receives a successful response from the Token Endpoint.
+ *
+ * This class associates the {@link #getClientRegistration() Client}
+ * to the {@link #getAccessToken() Access Token}
+ * granted/authorized by the {@link #getPrincipalName() Resource Owner}, along with
+ * the {@link #getIdToken() ID Token} which contains Claims about the authentication of the End-User.
*
* @author Joe Grandja
* @since 5.0
* @see IdToken
- * @see OAuth2ClientAuthenticationToken
+ * @see AuthorizedClient
* @see 3.1.3.3 Successful Token Response
*/
-public class OidcClientAuthenticationToken extends OAuth2ClientAuthenticationToken {
+public class OidcAuthorizedClient extends AuthorizedClient {
private final IdToken idToken;
- public OidcClientAuthenticationToken(ClientRegistration clientRegistration,
- AccessToken accessToken, IdToken idToken) {
+ public OidcAuthorizedClient(ClientRegistration clientRegistration, String principalName,
+ AccessToken accessToken, IdToken idToken) {
- super(clientRegistration, accessToken);
+ super(clientRegistration, principalName, accessToken);
Assert.notNull(idToken, "idToken cannot be null");
this.idToken = idToken;
}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/userinfo/OidcUserService.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/userinfo/OidcUserService.java
index b054e92da7..1a5a45d278 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/userinfo/OidcUserService.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/oidc/client/authentication/userinfo/OidcUserService.java
@@ -16,15 +16,15 @@
package org.springframework.security.oauth2.oidc.client.authentication.userinfo;
import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.oauth2.client.authentication.AuthorizedClient;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.client.authentication.OAuth2ClientAuthenticationToken;
import org.springframework.security.oauth2.client.authentication.userinfo.NimbusUserInfoRetriever;
import org.springframework.security.oauth2.client.authentication.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.client.authentication.userinfo.UserInfoRetriever;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.security.oauth2.core.user.OAuth2User;
-import org.springframework.security.oauth2.oidc.client.authentication.OidcClientAuthenticationToken;
+import org.springframework.security.oauth2.oidc.client.authentication.OidcAuthorizedClient;
import org.springframework.security.oauth2.oidc.core.OidcScope;
import org.springframework.security.oauth2.oidc.core.UserInfo;
import org.springframework.security.oauth2.oidc.core.user.DefaultOidcUser;
@@ -47,7 +47,7 @@ import java.util.Set;
* @author Joe Grandja
* @since 5.0
* @see OAuth2UserService
- * @see OidcClientAuthenticationToken
+ * @see OidcAuthorizedClient
* @see DefaultOidcUser
* @see UserInfo
* @see UserInfoRetriever
@@ -59,12 +59,12 @@ public class OidcUserService implements OAuth2UserService {
Arrays.asList(OidcScope.PROFILE, OidcScope.EMAIL, OidcScope.ADDRESS, OidcScope.PHONE));
@Override
- public OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
- OidcClientAuthenticationToken oidcClientAuthentication = (OidcClientAuthenticationToken)clientAuthentication;
+ public OAuth2User loadUser(AuthorizedClient authorizedClient) throws OAuth2AuthenticationException {
+ OidcAuthorizedClient oidcAuthorizedClient = (OidcAuthorizedClient)authorizedClient;
UserInfo userInfo = null;
- if (this.shouldRetrieveUserInfo(oidcClientAuthentication)) {
- MapList of {@link OAuth2UserService}'s.
* non-null {@link OAuth2User} being returned.
*
* @author Joe Grandja
@@ -47,9 +47,9 @@ public class DelegatingOAuth2UserService implements OAuth2UserService {
}
@Override
- public OAuth2User loadUser(OAuth2ClientAuthenticationToken clientAuthentication) throws OAuth2AuthenticationException {
+ public OAuth2User loadUser(AuthorizedClient authorizedClient) throws OAuth2AuthenticationException {
OAuth2User oauth2User = this.userServices.stream()
- .map(userService -> userService.loadUser(clientAuthentication))
+ .map(userService -> userService.loadUser(authorizedClient))
.filter(Objects::nonNull)
.findFirst()
.orElse(null);
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/NimbusUserInfoRetriever.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/NimbusUserInfoRetriever.java
index 0a1ec337cf..b4684a1c0a 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/NimbusUserInfoRetriever.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/userinfo/NimbusUserInfoRetriever.java
@@ -28,7 +28,7 @@ import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationException;
-import org.springframework.security.oauth2.client.authentication.OAuth2ClientAuthenticationToken;
+import org.springframework.security.oauth2.client.authentication.AuthorizedClient;
import org.springframework.security.oauth2.core.OAuth2Error;
import org.springframework.util.Assert;
@@ -37,7 +37,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.Charset;
-import java.util.Map;
/**
* An implementation of a {@link UserInfoRetriever} that uses the Nimbus OAuth 2.0 SDK internally.
@@ -52,9 +51,9 @@ public class NimbusUserInfoRetriever implements UserInfoRetriever {
private final HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
@Override
- public