diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java
index b4b53811fd..3643f80f05 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/authentication/AuthorizationCodeAuthenticationProvider.java
@@ -155,7 +155,7 @@ public class AuthorizationCodeAuthenticationProvider implements AuthenticationPr
}
oauth2UserAuthentication.setDetails(oauth2ClientAuthentication.getDetails());
- this.accessTokenRepository.saveSecurityToken(accessToken, oauth2UserAuthentication);
+ this.accessTokenRepository.saveSecurityToken(accessToken, clientRegistration);
return oauth2UserAuthentication;
}
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java
index 98a8f08fb1..e548c559d0 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/InMemoryAccessTokenRepository.java
@@ -15,58 +15,73 @@
*/
package org.springframework.security.oauth2.client.token;
-import org.springframework.security.oauth2.client.authentication.OAuth2UserAuthenticationToken;
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
+import org.springframework.security.oauth2.client.registration.ClientRegistrationIdentifierStrategy;
import org.springframework.security.oauth2.core.AccessToken;
-import org.springframework.security.oauth2.core.user.OAuth2User;
-import org.springframework.security.oauth2.oidc.core.user.OidcUser;
import org.springframework.util.Assert;
+import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
- * A basic implementation of a {@link SecurityTokenRepository}
- * that stores {@link AccessToken}(s) in-memory.
+ * A {@link SecurityTokenRepository} that associates an {@link AccessToken}
+ * to a {@link ClientRegistration Client} and stores it in-memory.
*
* @author Joe Grandja
* @since 5.0
* @see SecurityTokenRepository
* @see AccessToken
+ * @see ClientRegistration
*/
public final class InMemoryAccessTokenRepository implements SecurityTokenRepository {
+ private final ClientRegistrationIdentifierStrategy identifierStrategy = new AuthorizedClientIdentifierStrategy();
private final Map accessTokens = new HashMap<>();
@Override
- public AccessToken loadSecurityToken(OAuth2UserAuthenticationToken authentication) {
- Assert.notNull(authentication, "authentication cannot be null");
- return this.accessTokens.get(this.resolveAuthenticationKey(authentication));
+ public AccessToken loadSecurityToken(ClientRegistration registration) {
+ Assert.notNull(registration, "registration cannot be null");
+ return this.accessTokens.get(this.identifierStrategy.getIdentifier(registration));
}
@Override
- public void saveSecurityToken(AccessToken accessToken, OAuth2UserAuthenticationToken authentication) {
+ public void saveSecurityToken(AccessToken accessToken, ClientRegistration registration) {
Assert.notNull(accessToken, "accessToken cannot be null");
- Assert.notNull(authentication, "authentication cannot be null");
- this.accessTokens.put(this.resolveAuthenticationKey(authentication), accessToken);
+ Assert.notNull(registration, "registration cannot be null");
+ this.accessTokens.put(this.identifierStrategy.getIdentifier(registration), accessToken);
}
@Override
- public void removeSecurityToken(OAuth2UserAuthenticationToken authentication) {
- Assert.notNull(authentication, "authentication cannot be null");
- this.accessTokens.remove(this.resolveAuthenticationKey(authentication));
+ public void removeSecurityToken(ClientRegistration registration) {
+ Assert.notNull(registration, "registration cannot be null");
+ this.accessTokens.remove(this.identifierStrategy.getIdentifier(registration));
}
- private String resolveAuthenticationKey(OAuth2UserAuthenticationToken authentication) {
- String authenticationKey;
+ /**
+ * A client is considered "authorized", if it receives a successful response from the Token Endpoint.
+ *
+ * @see Section 4.1.3 Access Token Request
+ * @see Section 5.1 Access Token Response
+ */
+ private static class AuthorizedClientIdentifierStrategy implements ClientRegistrationIdentifierStrategy {
- OAuth2User oauth2User = (OAuth2User) authentication.getPrincipal();
- if (OidcUser.class.isAssignableFrom(oauth2User.getClass())) {
- OidcUser oidcUser = (OidcUser)oauth2User;
- authenticationKey = oidcUser.getIssuer().toString() + "-" + oidcUser.getSubject();
- } else {
- authenticationKey = authentication.getClientAuthentication().getClientRegistration()
- .getProviderDetails().getUserInfoUri() + "-" + oauth2User.getName();
+ @Override
+ public String getIdentifier(ClientRegistration clientRegistration) {
+ StringBuilder builder = new StringBuilder();
+
+ // Access Token Request attributes
+ builder.append("[").append(clientRegistration.getAuthorizationGrantType().getValue()).append("]");
+ builder.append("[").append(clientRegistration.getRedirectUri()).append("]");
+ builder.append("[").append(clientRegistration.getClientId()).append("]");
+
+ // Access Token Response attributes
+ builder.append("[").append(clientRegistration.getScope().toString()).append("]");
+
+ // Client alias is unique as well
+ builder.append("[").append(clientRegistration.getClientAlias()).append("]");
+
+ return Base64.getEncoder().encodeToString(builder.toString().getBytes());
}
-
- return authenticationKey;
}
}
+
diff --git a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/SecurityTokenRepository.java b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/SecurityTokenRepository.java
index 47758104c1..ded51d04b2 100644
--- a/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/SecurityTokenRepository.java
+++ b/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/token/SecurityTokenRepository.java
@@ -15,22 +15,25 @@
*/
package org.springframework.security.oauth2.client.token;
-import org.springframework.security.oauth2.client.authentication.OAuth2UserAuthenticationToken;
+import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.core.SecurityToken;
/**
* Implementations of this interface are responsible for the persistence
- * of {@link SecurityToken}(s) that are associated to an {@link OAuth2UserAuthenticationToken}.
+ * and association of an OAuth 2.0 / OpenID Connect 1.0
+ * {@link SecurityToken} to a {@link ClientRegistration Client}.
*
* @author Joe Grandja
* @since 5.0
+ * @see SecurityToken
+ * @see ClientRegistration
*/
public interface SecurityTokenRepository {
- T loadSecurityToken(OAuth2UserAuthenticationToken authentication);
+ T loadSecurityToken(ClientRegistration registration);
- void saveSecurityToken(T securityToken, OAuth2UserAuthenticationToken authentication);
+ void saveSecurityToken(T securityToken, ClientRegistration registration);
- void removeSecurityToken(OAuth2UserAuthenticationToken authentication);
+ void removeSecurityToken(ClientRegistration registration);
}