diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServices.java b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServices.java index 14c695bd21d..98b74caee68 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServices.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServices.java @@ -127,7 +127,7 @@ import static org.cloudfoundry.identity.uaa.oauth.token.TokenConstants.GRANT_TYPE_USER_TOKEN; import static org.cloudfoundry.identity.uaa.oauth.token.TokenConstants.REFRESH_TOKEN_SUFFIX; import static org.cloudfoundry.identity.uaa.oauth.token.TokenConstants.REQUEST_TOKEN_FORMAT; -import static org.cloudfoundry.identity.uaa.util.TokenValidation.validate; +import static org.cloudfoundry.identity.uaa.util.TokenValidation.validateAccessToken; import static org.springframework.util.StringUtils.hasText; @@ -1069,7 +1069,7 @@ protected TokenValidation validateToken(String token) { token = revocableToken.getValue(); } - tokenValidation = validate(token) + tokenValidation = validateAccessToken(token) .checkRevocableTokenStore(tokenProvisioning) .throwIfInvalid(); Jwt tokenJwt = tokenValidation.getJwt(); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/XOAuthAuthenticationManager.java b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/XOAuthAuthenticationManager.java index 834b5cd97e3..17955f58310 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/XOAuthAuthenticationManager.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/provider/oauth/XOAuthAuthenticationManager.java @@ -100,7 +100,7 @@ import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.GROUP_ATTRIBUTE_NAME; import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.PHONE_NUMBER_ATTRIBUTE_NAME; import static org.cloudfoundry.identity.uaa.provider.ExternalIdentityProviderDefinition.USER_NAME_ATTRIBUTE_NAME; -import static org.cloudfoundry.identity.uaa.util.TokenValidation.validate; +import static org.cloudfoundry.identity.uaa.util.TokenValidation.validateAccessToken; import static org.cloudfoundry.identity.uaa.util.UaaHttpRequestUtils.isAcceptedInvitationAuthentication; import static org.springframework.util.StringUtils.hasText; import static org.springframework.util.StringUtils.isEmpty; @@ -511,11 +511,11 @@ private TokenValidation validateToken(String idToken, AbstractXOAuthIdentityProv TokenValidation validation; if (tokenServices.getTokenEndpoint().equals(config.getIssuer())) { tokenKey = getTokenKeyForUaaOrigin(); - validation = validate(idToken) + validation = validateAccessToken(idToken) .checkSignature(new ChainedSignatureVerifier(tokenKey)); } else { tokenKey = getTokenKeyFromOAuth(config); - validation = validate(idToken) + validation = validateAccessToken(idToken) .checkSignature(new ChainedSignatureVerifier(tokenKey)) .checkIssuer((isEmpty(config.getIssuer()) ? config.getTokenUrl().toString() : config.getIssuer())) .checkAudience(config.getRelyingPartyId()); diff --git a/server/src/main/java/org/cloudfoundry/identity/uaa/util/TokenValidation.java b/server/src/main/java/org/cloudfoundry/identity/uaa/util/TokenValidation.java index ad2bcaadf42..4db327a7810 100644 --- a/server/src/main/java/org/cloudfoundry/identity/uaa/util/TokenValidation.java +++ b/server/src/main/java/org/cloudfoundry/identity/uaa/util/TokenValidation.java @@ -15,6 +15,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.cloudfoundry.identity.uaa.oauth.KeyInfo; import org.cloudfoundry.identity.uaa.oauth.TokenRevokedException; import org.cloudfoundry.identity.uaa.oauth.jwt.Jwt; import org.cloudfoundry.identity.uaa.oauth.jwt.JwtHelper; @@ -22,6 +23,8 @@ import org.cloudfoundry.identity.uaa.oauth.token.RevocableToken; import org.cloudfoundry.identity.uaa.oauth.token.RevocableTokenProvisioning; import org.cloudfoundry.identity.uaa.user.UaaUser; +import org.cloudfoundry.identity.uaa.user.UaaUserDatabase; +import org.cloudfoundry.identity.uaa.zone.ClientServicesExtension; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; import org.flywaydb.core.internal.util.StringUtils; import org.springframework.dao.EmptyResultDataAccessException; @@ -73,7 +76,11 @@ public class TokenValidation { private final boolean decoded; // this is used to avoid checking claims on tokens that had errors when decoding private final List validationErrors = new ArrayList<>(); - public static TokenValidation validate(String tokenJwtValue) { + public static TokenValidation validateAccessToken(String tokenJwtValue) { + return new TokenValidation(tokenJwtValue); + } + + public static TokenValidation validateRefreshToken(String tokenJwtValue) { return new TokenValidation(tokenJwtValue); } @@ -104,9 +111,36 @@ private TokenValidation(String token) { this.claims = new HashMap<>(); } + if (tokenJwt != null) { + validateHeader(tokenJwt); + } + this.decoded = isValid(); } + public TokenValidation validateHeader(Jwt tokenJwt) { + String kid = tokenJwt.getHeader().getKid(); + if (kid == null) { + validationErrors.add( + new InvalidTokenException("kid claim not found in JWT token header") + ); + return this; + } + + KeyInfo signingKey = KeyInfo.getKey(kid); + if (signingKey == null) { + validationErrors.add( + new InvalidTokenException(String.format( + "Token header claim [kid] references unknown signing key : [%s]", kid + )) + ); + return this; + } + + SignatureVerifier signatureVerifier = signingKey.getVerifier(); + return checkSignature(signatureVerifier); + } + public boolean isValid() { return validationErrors.size() == 0; } @@ -509,4 +543,25 @@ public TokenValidation checkAccessToken() { return this; } + public ClientDetails getClientDetails(ClientServicesExtension clientDetailsService) { + String clientId = (String) claims.get(CID); + try { + return clientDetailsService.loadClientByClientId(clientId, IdentityZoneHolder.get().getId()); + } catch (NoSuchClientException x) { + //happens if the client is deleted and token exist + throw new InvalidTokenException("Invalid client ID "+clientId); + } + } + + public UaaUser getUserDetails(UaaUserDatabase userDatabase) { + String userId = (String) claims.get(USER_ID); + if( UaaTokenUtils.isUserToken(claims)) { + try { + return userDatabase.retrieveUserById(userId); + } catch (UsernameNotFoundException e) { + throw new InvalidTokenException("Token bears a non-existent user ID: " + userId); + } + } + return null; + } } diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java index 1e94a0baccf..d7ea10ecd66 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/oauth/UaaTokenServicesTests.java @@ -99,6 +99,7 @@ import static org.cloudfoundry.identity.uaa.oauth.UaaTokenServices.UAA_REFRESH_TOKEN; import static org.cloudfoundry.identity.uaa.oauth.client.ClientConstants.REQUIRED_USER_GROUPS; import static org.cloudfoundry.identity.uaa.oauth.client.ClientDetailsModification.SECRET; +import static org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants.SCOPE; import static org.cloudfoundry.identity.uaa.oauth.token.TokenConstants.OPAQUE; import static org.cloudfoundry.identity.uaa.oauth.token.TokenConstants.REQUEST_TOKEN_FORMAT; import static org.cloudfoundry.identity.uaa.oauth.token.TokenConstants.TokenFormat.JWT; @@ -141,6 +142,8 @@ import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Matchers.anyString; +import static org.mockito.ArgumentMatchers.isNotNull; +import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -1941,7 +1944,7 @@ public void validate_token_client_gone() throws Exception { @Test public void opaque_tokens_validate_signature() throws Exception { expectedEx.expect(InvalidTokenException.class); - expectedEx.expectMessage("Invalid key ID: testKey"); + expectedEx.expectMessage("Token header claim [kid] references unknown signing key : [testKey]"); Consumer setup = (ignore) -> { Map < String, String > keys = new HashMap<>(); diff --git a/server/src/test/java/org/cloudfoundry/identity/uaa/util/TokenValidationTest.java b/server/src/test/java/org/cloudfoundry/identity/uaa/util/TokenValidationTest.java index 49bdb2103a7..0bcf735955b 100644 --- a/server/src/test/java/org/cloudfoundry/identity/uaa/util/TokenValidationTest.java +++ b/server/src/test/java/org/cloudfoundry/identity/uaa/util/TokenValidationTest.java @@ -13,14 +13,17 @@ package org.cloudfoundry.identity.uaa.util; +import org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants; import org.cloudfoundry.identity.uaa.oauth.token.RevocableToken; import org.cloudfoundry.identity.uaa.oauth.token.RevocableTokenProvisioning; import org.cloudfoundry.identity.uaa.user.InMemoryUaaUserDatabase; import org.cloudfoundry.identity.uaa.user.MockUaaUserDatabase; import org.cloudfoundry.identity.uaa.user.UaaUser; import org.cloudfoundry.identity.uaa.user.UaaUserDatabase; +import org.cloudfoundry.identity.uaa.zone.IdentityZone; import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder; -import org.hamcrest.CoreMatchers; +import org.cloudfoundry.identity.uaa.zone.IdentityZoneProvisioning; +import org.cloudfoundry.identity.uaa.zone.InMemoryClientServicesExtentions; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -33,6 +36,7 @@ import org.springframework.security.jwt.crypto.sign.Signer; import org.springframework.security.oauth2.common.exceptions.InsufficientScopeException; import org.springframework.security.oauth2.common.exceptions.InvalidTokenException; +import org.springframework.security.oauth2.provider.ClientDetails; import org.springframework.security.oauth2.provider.client.BaseClientDetails; import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService; @@ -49,13 +53,14 @@ import static org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants.EMAIL; import static org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants.JTI; import static org.cloudfoundry.identity.uaa.oauth.token.ClaimConstants.USER_NAME; -import static org.cloudfoundry.identity.uaa.util.TokenValidation.validate; +import static org.cloudfoundry.identity.uaa.util.TokenValidation.validateAccessToken; import static org.cloudfoundry.identity.uaa.util.UaaMapUtils.entry; import static org.cloudfoundry.identity.uaa.util.UaaMapUtils.map; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.hasItems; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.not; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.hasItem; @@ -64,6 +69,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; @@ -84,19 +90,32 @@ public class TokenValidationTest { private Map content; private Signer signer; private RevocableTokenProvisioning revocableTokenProvisioning; - private InMemoryClientDetailsService clientDetailsService; + private InMemoryClientServicesExtentions clientDetailsService; private UaaUserDatabase userDb; private UaaUser uaaUser; private BaseClientDetails uaaClient; private Collection uaaUserGroups; + private IdentityZoneProvisioning identityZoneProvisioning; @Rule public ExpectedException expectedException = ExpectedException.none(); @Before public void setup() { + String defaultKeyId = "some-key-id"; + + IdentityZone uaaZone = IdentityZone.getUaa(); + uaaZone.getConfig().getTokenPolicy().setKeys( + map(entry(defaultKeyId, "foobar")) + ); + identityZoneProvisioning = mock(IdentityZoneProvisioning.class); + when(identityZoneProvisioning.retrieve(anyString())).thenReturn(uaaZone); + + IdentityZoneHolder.setProvisioning(identityZoneProvisioning); + header = map( - entry("alg", "HS256") + entry("alg", "HS256"), + entry("kid", defaultKeyId) ); content = map( @@ -124,10 +143,11 @@ public void setup() { signer = new MacSigner("secret"); - clientDetailsService = new InMemoryClientDetailsService(); + clientDetailsService = new InMemoryClientServicesExtentions(); uaaClient = new BaseClientDetails("app", "acme", "acme.dev", "authorization_code", ""); uaaClient.addAdditionalInformation(REQUIRED_USER_GROUPS, Arrays.asList()); - clientDetailsService.setClientDetailsStore(Collections.singletonMap(CLIENT_ID, uaaClient)); + clientDetailsService.setClientDetailsStore(IdentityZone.getUaa().getId(), + Collections.singletonMap(CLIENT_ID, uaaClient)); revocableTokenProvisioning = mock(RevocableTokenProvisioning.class); when(revocableTokenProvisioning.retrieve("8b14f193-8212-4af2-9927-e3ae903f94a6", IdentityZoneHolder.get().getId())) @@ -144,6 +164,89 @@ public void setup() { } + @Test + public void validate_KeyId_isPresent() { + header = map(entry("alg", "HS256")); + String token = getToken(); + + TokenValidation validation = TokenValidation.validateAccessToken(token); + + assertThat(validation.getValidationErrors(), not(empty())); + assertThat(validation.getValidationErrors(), hasSize(1)); + assertThat(validation.getValidationErrors().get(0).getMessage(), + equalTo("kid claim not found in JWT token header")); + } + + @Test + public void validate_KeyId_actuallyExists() { + String kid = "garbage"; + header.put("kid", kid); + + String token = getToken(); + + TokenValidation validation = TokenValidation.validateAccessToken(token); + + assertThat(validation.getValidationErrors(), not(empty())); + assertThat(validation.getValidationErrors(), hasSize(1)); + assertThat(validation.getValidationErrors().get(0).getMessage(), + equalTo("Token header claim [kid] references unknown signing key : [garbage]")); + } + + @Test + public void testGetClientById() { + String token = getToken(); + + ClientDetails clientDetails = TokenValidation.validateAccessToken(token) + .getClientDetails(clientDetailsService); + + assertThat(clientDetails.getClientId(), equalTo(content.get("cid"))); + } + + @Test + public void testGetClientById_invalidId() { + String invalidClientId = "invalid-client-id"; + content.put("cid", invalidClientId); + String token = getToken(); + + expectedException.expect(InvalidTokenException.class); + expectedException.expectMessage("Invalid client ID " + invalidClientId); + + TokenValidation.validateAccessToken(token).getClientDetails(clientDetailsService); + } + + @Test + public void testGetUserById() { + String token = getToken(); + + UaaUser user = TokenValidation.validateAccessToken(token).getUserDetails(userDb); + + assertThat(user, notNullValue()); + assertThat(user.getUsername(), equalTo("marissa")); + assertThat(user.getEmail(), equalTo("marissa@test.org")); + } + + @Test + public void testGetUserById_notUserToken() { + content.put("grant_type", "client_credentials"); + String token = getToken(); + + UaaUser user = TokenValidation.validateAccessToken(token).getUserDetails(userDb); + + assertThat(user, nullValue()); + } + + @Test + public void testGetUserById_invalidUserId() { + String invalidUserId = "invalid-user-id"; + content.put(ClaimConstants.USER_ID, invalidUserId); + String token = getToken(); + + expectedException.expect(InvalidTokenException.class); + expectedException.expectMessage("Token bears a non-existent user ID: " + invalidUserId); + + UaaUser user = TokenValidation.validateAccessToken(token).getUserDetails(userDb); + } + private String getToken() { return getToken(EMPTY_LIST); } @@ -157,7 +260,7 @@ private String getToken(Collection excludedClaims) { @Test public void validate_required_groups_is_invoked() throws Exception { - TokenValidation validation = spy(validate(getToken())); + TokenValidation validation = spy(validateAccessToken(getToken())); validation.checkClientAndUser(uaaClient, uaaUser); verify(validation, times(1)) @@ -184,7 +287,7 @@ public void validate_required_groups_is_invoked() throws Exception { @Test public void required_groups_are_present() throws Exception { - TokenValidation validation = validate(getToken()); + TokenValidation validation = validateAccessToken(getToken()); uaaClient.addAdditionalInformation(REQUIRED_USER_GROUPS, uaaUserGroups); assertTrue(validation.checkClientAndUser(uaaClient, uaaUser).throwIfInvalid().isValid()); } @@ -192,7 +295,7 @@ public void required_groups_are_present() throws Exception { @Test public void required_groups_are_missing() throws Exception { - TokenValidation validation = validate(getToken()); + TokenValidation validation = validateAccessToken(getToken()); uaaUserGroups.add("group-missing-from-user"); uaaClient.addAdditionalInformation(REQUIRED_USER_GROUPS, uaaUserGroups); assertFalse(validation.checkClientAndUser(uaaClient, uaaUser).isValid()); @@ -206,7 +309,7 @@ public void required_groups_are_missing() throws Exception { @Test public void validateToken() throws Exception { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkSignature(verifier) .checkIssuer("http://localhost:8080/uaa/oauth/token") .checkClient((clientId) -> clientDetailsService.loadClientByClientId(clientId)) @@ -225,10 +328,10 @@ public void validateToken() throws Exception { } @Test - public void validateAccessToken() throws Exception { + public void testValidateAccessToken() throws Exception { content.put(JTI, "8b14f193-8212-4af2-9927-e3ae903f94a6-r"); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkAccessToken(); assertThat(validation.getValidationErrors(), not(empty())); @@ -243,7 +346,7 @@ public void validateAccessToken() throws Exception { public void validateAccessToken_with_dashR_in_JTI_should_fail_validation() throws Exception { content.put(JTI, "8b14f193-r-8212-4af2-9927-e3ae903f94a6"); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkAccessToken(); assertThat(validation.getValidationErrors(), empty()); @@ -254,7 +357,7 @@ public void validateAccessToken_with_dashR_in_JTI_should_fail_validation() throw public void validateAccessToken_without_jti_should_fail_validation() throws Exception { content.put(JTI, null); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkAccessToken(); assertThat(validation.getValidationErrors(), hasSize(1)); @@ -266,7 +369,7 @@ public void validateAccessToken_without_jti_should_fail_validation() throws Exce @Test public void validateToken_Without_Email_And_Username() throws Exception { - TokenValidation validation = validate(getToken(Arrays.asList(EMAIL, USER_NAME))) + TokenValidation validation = validateAccessToken(getToken(Arrays.asList(EMAIL, USER_NAME))) .checkSignature(verifier) .checkIssuer("http://localhost:8080/uaa/oauth/token") .checkClient((clientId) -> clientDetailsService.loadClientByClientId(clientId)) @@ -287,7 +390,7 @@ public void validateToken_Without_Email_And_Username() throws Exception { public void tokenSignedWithDifferentKey() throws Exception { signer = new MacSigner("some_other_key"); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkSignature(verifier); // opaque tokens should remain valid even through a signing key being removed assertFalse(validation.isValid()); @@ -296,14 +399,14 @@ public void tokenSignedWithDifferentKey() throws Exception { @Test public void invalidJwt() throws Exception { - TokenValidation validation = validate("invalid.jwt.token"); + TokenValidation validation = validateAccessToken("invalid.jwt.token"); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); } @Test public void tokenWithInvalidIssuer() throws Exception { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkIssuer("http://wrong.issuer/"); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -312,7 +415,7 @@ public void tokenWithInvalidIssuer() throws Exception { @Test public void emptyBodyJwt() throws Exception { content = null; - TokenValidation validation = validate(getToken()); + TokenValidation validation = validateAccessToken(getToken()); assertThat(validation.getValidationErrors(), empty()); assertTrue("Token with no claims is valid after decoding.", validation.isValid()); @@ -322,7 +425,7 @@ public void emptyBodyJwt() throws Exception { @Test public void expiredToken() { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkExpiry(oneSecondAfterTheTokenExpires); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -332,7 +435,7 @@ public void expiredToken() { public void nonExistentUser() { UaaUserDatabase userDb = new InMemoryUaaUserDatabase(Collections.emptySet()); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkUser((uid) -> userDb.retrieveUserById(uid)); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -346,7 +449,7 @@ public void userHadScopeRevoked() { .withEmail("marissa@test.org") .withAuthorities(Collections.singletonList(new SimpleGrantedAuthority("a.different.scope")))); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkUser((uid) -> userDb.retrieveUserById(uid)); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -354,7 +457,7 @@ public void userHadScopeRevoked() { @Test public void tokenHasInsufficientScope() { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkScopesInclude("a.different.scope"); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InsufficientScopeException.class))); @@ -362,7 +465,7 @@ public void tokenHasInsufficientScope() { @Test public void tokenContainsRevokedScope() { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkScopesWithin("a.different.scope"); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -372,7 +475,7 @@ public void tokenContainsRevokedScope() { public void nonExistentClient() { InMemoryClientDetailsService clientDetailsService = new InMemoryClientDetailsService(); clientDetailsService.setClientDetailsStore(Collections.emptyMap()); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkClient((clientId) -> clientDetailsService.loadClientByClientId(clientId)); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -383,7 +486,7 @@ public void clientHasScopeRevoked() { InMemoryClientDetailsService clientDetailsService = new InMemoryClientDetailsService(); clientDetailsService.setClientDetailsStore(Collections.singletonMap("app", new BaseClientDetails("app", "acme", "a.different.scope", "authorization_code", ""))); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkClient((clientId) -> clientDetailsService.loadClientByClientId(clientId)); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -391,25 +494,24 @@ public void clientHasScopeRevoked() { @Test public void clientRevocationHashChanged() { - TokenValidation validation = validate(getToken()).checkRevocationSignature(Collections.singletonList("New-Hash")); + TokenValidation validation = validateAccessToken(getToken()).checkRevocationSignature(Collections.singletonList("New-Hash")); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); } @Test public void clientRevocationHashChanged_and_Should_Pass() { - TokenValidation validation = validate(getToken()).checkRevocationSignature(Arrays.asList("fa1c787d", "New-Hash")); + TokenValidation validation = validateAccessToken(getToken()).checkRevocationSignature(Arrays.asList("fa1c787d", "New-Hash")); assertTrue(validation.isValid()); - validation = validate(getToken()).checkRevocationSignature(Arrays.asList("New-Hash", "fa1c787d")); + validation = validateAccessToken(getToken()).checkRevocationSignature(Arrays.asList("New-Hash", "fa1c787d")); assertTrue(validation.isValid()); } - @Test public void incorrectAudience() { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkAudience("app", "somethingelse"); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -417,7 +519,7 @@ public void incorrectAudience() { @Test public void emptyAudience() { - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkAudience(""); assertFalse(validation.isValid()); assertThat(validation.getValidationErrors(), hasItem(instanceOf(InvalidTokenException.class))); @@ -429,7 +531,7 @@ public void tokenIsRevoked() { when(revocableTokenProvisioning.retrieve("8b14f193-8212-4af2-9927-e3ae903f94a6", IdentityZoneHolder.get().getId())) .thenThrow(new EmptyResultDataAccessException(1)); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkRevocableTokenStore(revocableTokenProvisioning); assertFalse(validation.isValid()); @@ -444,7 +546,7 @@ public void nonRevocableToken() { content.remove("revocable"); - TokenValidation validation = validate(getToken()) + TokenValidation validation = validateAccessToken(getToken()) .checkRevocableTokenStore(revocableTokenProvisioning); verifyZeroInteractions(revocableTokenProvisioning);