diff --git a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java index ecb0f9a95..45e30b871 100644 --- a/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java +++ b/openid-connect-common/src/main/java/org/mitre/openid/connect/service/OIDCTokenService.java @@ -61,4 +61,11 @@ public interface OIDCTokenService { */ public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client); + /** + * Rotate the registration or resource token for a client + * @param client + * @return + */ + public OAuth2AccessTokenEntity rotateRegistrationAccessTokenForClient(ClientDetailsEntity client); + } \ No newline at end of file diff --git a/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java b/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java index add29adbc..05a2bf508 100644 --- a/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java +++ b/openid-connect-server/src/main/java/org/mitre/oauth2/web/TokenAPI.java @@ -162,7 +162,7 @@ public class TokenAPI { ClientDetailsEntity client = clientService.loadClientByClientId(clientId); if (client != null) { - OAuth2AccessTokenEntity token = oidcTokenService.createRegistrationAccessToken(client); + OAuth2AccessTokenEntity token = oidcTokenService.rotateRegistrationAccessTokenForClient(client); token = tokenService.saveAccessToken(token); if (token != null) { diff --git a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java index 222cf2a58..5ea04a722 100644 --- a/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java +++ b/openid-connect-server/src/main/java/org/mitre/openid/connect/service/impl/DefaultOIDCTokenService.java @@ -40,7 +40,6 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import org.springframework.security.core.token.TokenService; import org.springframework.security.oauth2.provider.OAuth2Authentication; import org.springframework.security.oauth2.provider.OAuth2Request; import org.springframework.stereotype.Service; @@ -207,8 +206,39 @@ public class DefaultOIDCTokenService implements OIDCTokenService { @Override public OAuth2AccessTokenEntity createRegistrationAccessToken(ClientDetailsEntity client) { + return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.REGISTRATION_TOKEN_SCOPE)); + + } + + /** + * @param client + * @return + */ + @Override + public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client) { + + return createAssociatedToken(client, Sets.newHashSet(SystemScopeService.RESOURCE_TOKEN_SCOPE)); + + } + + @Override + public OAuth2AccessTokenEntity rotateRegistrationAccessTokenForClient(ClientDetailsEntity client) { // revoke any previous tokens OAuth2AccessTokenEntity oldToken = tokenService.getRegistrationAccessTokenForClient(client); + if (oldToken != null) { + Set scope = oldToken.getScope(); + tokenService.revokeAccessToken(oldToken); + return createAssociatedToken(client, scope); + } else { + return null; + } + + } + + private OAuth2AccessTokenEntity createAssociatedToken(ClientDetailsEntity client, Set scope) { + + // revoke any previous tokens that might exist, just to be sure + OAuth2AccessTokenEntity oldToken = tokenService.getRegistrationAccessTokenForClient(client); if (oldToken != null) { tokenService.revokeAccessToken(oldToken); } @@ -218,53 +248,12 @@ public class DefaultOIDCTokenService implements OIDCTokenService { Map authorizationParameters = Maps.newHashMap(); OAuth2Request clientAuth = new OAuth2Request(authorizationParameters, client.getClientId(), Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true, - Sets.newHashSet(SystemScopeService.REGISTRATION_TOKEN_SCOPE), null, null, null, null); + scope, null, null, null, null); OAuth2Authentication authentication = new OAuth2Authentication(clientAuth, null); OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); token.setClient(client); - token.setScope(Sets.newHashSet(SystemScopeService.REGISTRATION_TOKEN_SCOPE)); - - AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); - authHolder.setAuthentication(authentication); - authHolder = authenticationHolderRepository.save(authHolder); - token.setAuthenticationHolder(authHolder); - - JWTClaimsSet claims = new JWTClaimsSet(); - - claims.setAudience(Lists.newArrayList(client.getClientId())); - claims.setIssuer(configBean.getIssuer()); - claims.setIssueTime(new Date()); - claims.setExpirationTime(token.getExpiration()); - claims.setJWTID(UUID.randomUUID().toString()); // set a random NONCE in the middle of it - - JWSAlgorithm signingAlg = jwtService.getDefaultSigningAlgorithm(); - SignedJWT signed = new SignedJWT(new JWSHeader(signingAlg), claims); - - jwtService.signJwt(signed); - - token.setJwt(signed); - - return token; - } - - /** - * @param client - * @return - * @throws AuthenticationException - */ - @Override - public OAuth2AccessTokenEntity createResourceAccessToken(ClientDetailsEntity client) { - - Map authorizationParameters = Maps.newHashMap(); - OAuth2Request clientAuth = new OAuth2Request(authorizationParameters, client.getClientId(), - Sets.newHashSet(new SimpleGrantedAuthority("ROLE_CLIENT")), true, - Sets.newHashSet(SystemScopeService.RESOURCE_TOKEN_SCOPE), null, null, null, null); - OAuth2Authentication authentication = new OAuth2Authentication(clientAuth, null); - - OAuth2AccessTokenEntity token = new OAuth2AccessTokenEntity(); - token.setClient(client); - token.setScope(Sets.newHashSet(SystemScopeService.RESOURCE_TOKEN_SCOPE)); + token.setScope(scope); AuthenticationHolderEntity authHolder = new AuthenticationHolderEntity(); authHolder.setAuthentication(authentication);