@Override protected void validateJtiValue(String jtiValue) { if (jtiValue.endsWith(REFRESH_TOKEN_SUFFIX)) { throw new InvalidTokenException("Invalid access token.", null); } }
@Test public void testInvalidRefreshToken() { Map<String, String> map = new HashMap<>(); map.put("grant_type", "refresh_token"); AuthorizationRequest authorizationRequest = new AuthorizationRequest(map, null, null, null, null, null, false, null, null, null); String refreshTokenValue = "dasdasdasdasdas"; try { tokenServices.refreshAccessToken(refreshTokenValue, tokenSupport.requestFactory.createTokenRequest(authorizationRequest, "refresh_token")); fail("Expected Exception was not thrown"); } catch (InvalidTokenException e) { assertThat(e.getMessage(), not(containsString(refreshTokenValue))); } }
@Test void validateOldTokenAfterDeleteClientSecret() throws Exception { String clientId = "testclient" + generator.generate(); String scopes = "space.*.developer,space.*.admin,org.*.reader,org.123*.admin,*.*,*"; setUpClients(clientId, scopes, scopes, GRANT_TYPES, true); String body = mockMvc.perform(post("/oauth/token") .accept(MediaType.APPLICATION_JSON_VALUE) .with(httpBasic(clientId, SECRET)) .param("grant_type", "client_credentials") .param("client_id", clientId) .param("client_secret", SECRET)) .andExpect(status().isOk()) .andReturn().getResponse().getContentAsString(); Map<String, Object> bodyMap = JsonUtils.readValue(body, new TypeReference<Map<String, Object>>() { }); String access_token = (String) bodyMap.get("access_token"); assertNotNull(access_token); clientDetailsService.addClientSecret(clientId, "newSecret", IdentityZoneHolder.get().getId()); clientDetailsService.deleteClientSecret(clientId, IdentityZoneHolder.get().getId()); MockHttpServletResponse response = mockMvc.perform(post("/check_token") .header("Authorization", "Basic " + new String(Base64.encode("app:appclientsecret".getBytes()))) .param("token", access_token)) .andExpect(status().isBadRequest()) .andReturn().getResponse(); InvalidTokenException tokenRevokedException = JsonUtils.readValue(response.getContentAsString(), TokenRevokedException.class); assertEquals("invalid_token", tokenRevokedException.getOAuth2ErrorCode()); assertEquals("revocable signature mismatch", tokenRevokedException.getMessage()); }
@Test public void testLoadAuthenticationWithAnExpiredToken() { BaseClientDetails shortExpiryClient = tokenSupport.defaultClient; shortExpiryClient.setAccessTokenValiditySeconds(1); tokenSupport.clientDetailsService.setClientDetailsStore( IdentityZoneHolder.get().getId(), Collections.singletonMap(CLIENT_ID, shortExpiryClient) ); AuthorizationRequest authorizationRequest = new AuthorizationRequest(CLIENT_ID, tokenSupport.requestedAuthScopes); authorizationRequest.setResourceIds(new HashSet<>(tokenSupport.resourceIds)); Map<String, String> azParameters = new HashMap<>(authorizationRequest.getRequestParameters()); azParameters.put(GRANT_TYPE, GRANT_TYPE_AUTHORIZATION_CODE); authorizationRequest.setRequestParameters(azParameters); Authentication userAuthentication = tokenSupport.defaultUserAuthentication; OAuth2Authentication authentication = new OAuth2Authentication(authorizationRequest.createOAuth2Request(), userAuthentication); OAuth2AccessToken accessToken = tokenServices.createAccessToken(authentication); assertThat(accessToken, validFor(is(1))); when(tokenSupport.timeService.getCurrentTimeMillis()).thenReturn(2001L); try { tokenServices.loadAuthentication(accessToken.getValue()); fail("Expected Exception was not thrown"); } catch (InvalidTokenException e) { assertThat(e.getMessage(), not(containsString(accessToken.getValue()))); } }
@Override protected void validateJtiValue(String jtiValue) { if (!jtiValue.endsWith(REFRESH_TOKEN_SUFFIX)) { throw new InvalidTokenException("Invalid refresh token.", null); } }
fail("Expected Exception was not thrown"); } catch (InvalidTokenException e) { assertThat(e.getMessage(), not(containsString(accessToken.getRefreshToken().getValue())));
@Override protected void validateJtiValue(String jtiValue) { if (jtiValue.endsWith(REFRESH_TOKEN_SUFFIX)) { throw new InvalidTokenException("Invalid access token.", null); } } }
fail("Approval has been revoked"); } catch (InvalidTokenException x) { assertThat("Exception should be about approvals", x.getMessage().contains("some requested scopes are not approved"));
@Override public void verify(Map<String, Object> claims) throws InvalidTokenException { if (!CollectionUtils.isEmpty(claims) && claims.containsKey(ISS_CLAIM)) { String jwtIssuer = (String)claims.get(ISS_CLAIM); if (!jwtIssuer.equals(this.issuer.toString())) { throw new InvalidTokenException("Invalid Issuer (iss) claim: " + jwtIssuer); } } } }
@Test public void testClientSecret_Added_Token_Validation_Still_Works() { tokenSupport.defaultClient.setClientSecret(SECRET); AuthorizationRequest authorizationRequest = new AuthorizationRequest(CLIENT_ID, tokenSupport.requestedAuthScopes); authorizationRequest.setResourceIds(new HashSet<>(tokenSupport.resourceIds)); Map<String, String> azParameters = new HashMap<>(authorizationRequest.getRequestParameters()); azParameters.put(GRANT_TYPE, GRANT_TYPE_PASSWORD); authorizationRequest.setRequestParameters(azParameters); Authentication userAuthentication = tokenSupport.defaultUserAuthentication; OAuth2Authentication authentication = new OAuth2Authentication(authorizationRequest.createOAuth2Request(), userAuthentication); OAuth2AccessToken accessToken = tokenServices.createAccessToken(authentication); //normal token validation tokenServices.loadAuthentication(accessToken.getValue()); //add a 2nd secret tokenSupport.defaultClient.setClientSecret(tokenSupport.defaultClient.getClientSecret() + " newsecret"); tokenServices.loadAuthentication(accessToken.getValue()); //generate a token when we have two secrets OAuth2AccessToken accessToken2 = tokenServices.createAccessToken(authentication); //remove the 1st secret tokenSupport.defaultClient.setClientSecret("newsecret"); try { tokenServices.loadAuthentication(accessToken.getValue()); fail("Token should fail to validate on the revocation signature"); } catch (InvalidTokenException e) { assertTrue(e.getMessage().contains("revocable signature mismatch")); } tokenServices.loadAuthentication(accessToken2.getValue()); OAuth2AccessToken accessToken3 = tokenServices.createAccessToken(authentication); tokenServices.loadAuthentication(accessToken3.getValue()); }
protected TokenValidation checkExpiry(Instant asOf) { if (!claims.containsKey(EXP)) { throw new InvalidTokenException("Token does not bear an EXP claim.", null); } Object expClaim = claims.get(EXP); long expiry; try { expiry = (int) expClaim; if (asOf.getEpochSecond() > expiry) { throw new InvalidTokenException("Token expired at " + expiry, null); } } catch (ClassCastException ex) { throw new InvalidTokenException("Token bears an invalid or unparseable EXP claim.", ex); } return this; }
@ExceptionHandler @ResponseStatus(HttpStatus.BAD_REQUEST) @ResponseBody public AuthenticationError handleClientAuthenticationException(InvalidTokenException ex, HttpServletRequest request) { return new AuthenticationError("invalid_token", ex.getMessage()); }
public TokenValidation checkIssuer(String issuer) { if (issuer == null) { return this; } if (!claims.containsKey(ISS)) { throw new InvalidTokenException("Token does not bear an ISS claim.", null); } if (!equals(issuer, claims.get(ISS))) { throw new InvalidTokenException("Invalid issuer (" + claims.get(ISS) + ") for token did not match expected: " + issuer, null); } return this; }
@Override public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException { Map<String, Object> map = getMap(this.userInfoEndpointUrl, accessToken); if (map.containsKey("error")) { this.logger.debug("userinfo returned error: " + map.get("error")); throw new InvalidTokenException(accessToken); } return extractAuthentication(map); }
@Override public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException { Map<String, Object> map = getMap(this.userInfoEndpointUrl, accessToken); if (map.containsKey("error")) { this.logger.debug("userinfo returned error: " + map.get("error")); throw new InvalidTokenException(accessToken); } return extractAuthentication(map); }
protected TokenValidation checkRequiredUserGroups(Collection<String> requiredGroups, Collection<String> userGroups) { if (!UaaTokenUtils.hasRequiredUserGroups(requiredGroups, userGroups)) { throw new InvalidTokenException("User does not meet the client's required group criteria.", null); } return this; }
/** * Get a refresh token by its token value. */ @Override public OAuth2RefreshTokenEntity getRefreshToken(String refreshTokenValue) throws AuthenticationException { OAuth2RefreshTokenEntity refreshToken = tokenRepository.getRefreshTokenByValue(refreshTokenValue); if (refreshToken == null) { throw new InvalidTokenException("Refresh token for value " + refreshTokenValue + " was not found"); } else { return refreshToken; } }
public String getClientId(String tokenValue) { OAuth2Authentication authentication = tokenStore.readAuthentication(tokenValue); if (authentication == null) { throw new InvalidTokenException("Invalid access token: " + tokenValue); } OAuth2Request clientAuth = authentication.getOAuth2Request(); if (clientAuth == null) { throw new InvalidTokenException("Invalid access token (no client id): " + tokenValue); } return clientAuth.getClientId(); }
@Override public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException { MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>(); formData.add(tokenName, accessToken); HttpHeaders headers = new HttpHeaders(); headers.set("Authorization", getAuthorizationHeader(clientId, clientSecret)); Map<String, Object> map = postForMap(checkTokenEndpointUrl, formData, headers); if (map.containsKey("error")) { if (logger.isDebugEnabled()) { logger.debug("check_token returned error: " + map.get("error")); } throw new InvalidTokenException(accessToken); } // gh-838 if (!Boolean.TRUE.equals(map.get("active"))) { logger.debug("check_token returned active attribute: " + map.get("active")); throw new InvalidTokenException(accessToken); } return tokenConverter.extractAuthentication(map); }
protected TokenValidation checkAudience(Collection<String> clients) { if (!claims.containsKey(AUD)) { throw new InvalidTokenException("The token does not bear an AUD claim.", null); } Object audClaim = claims.get(AUD); List<String> audience; if (audClaim instanceof String) { audience = Collections.singletonList((String) audClaim); } else if (audClaim == null) { audience = Collections.emptyList(); } else { try { audience = ((List<?>) audClaim).stream() .map(s -> (String) s) .collect(toList()); } catch (ClassCastException ex) { throw new InvalidTokenException("The token's audience claim is invalid or unparseable.", ex); } } List<String> notInAudience = clients.stream().filter(c -> !audience.contains(c)).collect(toList()); if (!notInAudience.isEmpty()) { String joinedAudiences = notInAudience.stream().map(c -> "".equals(c) ? "EMPTY_VALUE" : c).collect(Collectors.joining(", ")); throw new InvalidTokenException("Some parties were not in the token audience: " + joinedAudiences, null); } return this; }