TokenValidationService { public TokenValidation validateToken(String token, boolean isAccessToken) { if (!UaaTokenUtils.isJwtToken(token)) { RevocableToken revocableToken; try { revocableToken = revocableTokenProvisioning.retrieve(token, IdentityZoneHolder.get().getId()); } catch (EmptyResultDataAccessException ex) { throw new TokenRevokedException("The token expired, was revoked, or the token ID is incorrect."); } token = revocableToken.getValue(); } TokenValidation tokenValidation = isAccessToken ? buildAccessTokenValidator(token, keyInfoService) : buildRefreshTokenValidator(token, keyInfoService); tokenValidation .checkRevocableTokenStore(revocableTokenProvisioning) .checkIssuer(tokenEndpointBuilder.getTokenEndpoint(IdentityZoneHolder.get())); ClientDetails client = tokenValidation.getClientDetails(multitenantClientServices); UaaUser user = tokenValidation.getUserDetails(userDatabase); tokenValidation .checkClientAndUser(client, user); List<String> clientSecrets = new ArrayList<>(); List<String> revocationSignatureList = new ArrayList<>(); if (client.getClientSecret() != null) { clientSecrets.addAll(Arrays.asList(client.getClientSecret().split(" "))); } else { revocationSignatureList.add(UaaTokenUtils.getRevocableTokenSignature(client, null, user)); } for (String clientSecret : clientSecrets) { revocationSignatureList.add(UaaTokenUtils.getRevocableTokenSignature(client, clientSecret, user)); } tokenValidation = tokenValidation.checkRevocationSignature(revocationSignatureList); return tokenValidation; } TokenValidationService(RevocableTokenProvisioning revocableTokenProvisioning,
                                  TokenEndpointBuilder tokenEndpointBuilder,
                                  UaaUserDatabase userDatabase,
                                  MultitenantClientServices multitenantClientServices,
                                  KeyInfoService keyInfoService); TokenValidation validateToken(String token, boolean isAccessToken); void setUserDatabase(UaaUserDatabase userDatabase);  }
@Test public void validation_happyPath() { String accessToken = UaaTokenUtils.constructToken(header, content, signer); tokenValidationService.validateToken(accessToken, true); }
@Test public void validation_enforcesKeyId() { expectedException.expect(InvalidTokenException.class); expectedException.expectMessage("Token header claim [kid] references unknown signing key : [testKey]"); header.put("kid", "testKey"); String accessToken = UaaTokenUtils.constructToken(header, content, signer); tokenValidationService.validateToken(accessToken, true); }
@Test public void validationFails_whenUserNotFound() { expectedException.expect(InvalidTokenException.class); expectedException.expectMessage("Token bears a non-existent user ID: " + userId); when(userDatabase.retrieveUserById(userId)).thenThrow(UsernameNotFoundException.class); String accessToken = UaaTokenUtils.constructToken(header, content, signer); tokenValidationService.validateToken(accessToken, true); }
@Test public void validationFails_whenClientNotFound() { expectedException.expect(InvalidTokenException.class); expectedException.expectMessage("Invalid client ID "+clientId); when(mockMultitenantClientServices.loadClientByClientId(clientId, IdentityZoneHolder.get().getId())).thenThrow(NoSuchClientException.class); String accessToken = UaaTokenUtils.constructToken(header, content, signer); tokenValidationService.validateToken(accessToken, true); }
@Test public void refreshToken_validatesWithScopeClaim_forBackwardsCompatibilityReasons() { Map<String, Object> content = map( entry(USER_ID, userId), entry(JTI, "abcdefg-r"), entry(CID, clientId), entry(SCOPE, Lists.newArrayList("foo.bar")) ); String refreshToken = UaaTokenUtils.constructToken(header, content, signer); tokenValidationService.validateToken(refreshToken, false); }
@Test public void refreshToken_validatesWithGrantedScopesClaim() { Map<String, Object> content = map( entry(USER_ID, userId), entry(JTI, "abcdefg-r"), entry(CID, clientId), entry(GRANTED_SCOPES, Lists.newArrayList("foo.bar")) ); String refreshToken = UaaTokenUtils.constructToken(header, content, signer); tokenValidationService.validateToken(refreshToken, false); }