private JWT parse(String token) { try { return JWTParser.parse(token); } catch (Exception ex) { throw new JwtException("An error occurred while attempting to decode the Jwt: " + ex.getMessage(), ex); } }
private OAuth2AuthenticationException onError(JwtException e) { OAuth2Error invalidRequest = invalidToken(e.getMessage()); return new OAuth2AuthenticationException(invalidRequest, e.getMessage()); }
private JWT parse(String token) { try { return JWTParser.parse(token); } catch (Exception ex) { throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex); } }
private OidcIdToken createOidcToken(ClientRegistration clientRegistration, OAuth2AccessTokenResponse accessTokenResponse) { JwtDecoder jwtDecoder = this.jwtDecoderFactory.createDecoder(clientRegistration); Jwt jwt; try { jwt = jwtDecoder.decode((String) accessTokenResponse.getAdditionalParameters().get(OidcParameterNames.ID_TOKEN)); } catch (JwtException ex) { OAuth2Error invalidIdTokenError = new OAuth2Error(INVALID_ID_TOKEN_ERROR_CODE, ex.getMessage(), null); throw new OAuth2AuthenticationException(invalidIdTokenError, invalidIdTokenError.toString(), ex); } OidcIdToken idToken = new OidcIdToken(jwt.getTokenValue(), jwt.getIssuedAt(), jwt.getExpiresAt(), jwt.getClaims()); return idToken; } }
private JWTClaimsSet createClaimsSet(JWT parsedToken, List<JWK> jwkList) { try { return this.jwtProcessor.process(parsedToken, new JWKContext(jwkList)); } catch (BadJOSEException | JOSEException e) { throw new JwtException("Failed to validate the token", e); } }
/** * Decode and validate the * <a href="https://tools.ietf.org/html/rfc6750#section-1.2" target="_blank">Bearer Token</a>. * * @param authentication the authentication request object. * * @return A successful authentication * @throws AuthenticationException if authentication failed for some reason */ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication; Jwt jwt; try { jwt = this.jwtDecoder.decode(bearer.getToken()); } catch (JwtException failed) { OAuth2Error invalidToken = invalidToken(failed.getMessage()); throw new OAuth2AuthenticationException(invalidToken, invalidToken.getDescription(), failed); } AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt); token.setDetails(bearer.getDetails()); return token; }
private Mono<Jwt> decode(SignedJWT parsedToken) { try { JWKSelector selector = this.jwkSelectorFactory .createSelector(parsedToken.getHeader()); return this.reactiveJwkSource.get(selector) .onErrorMap(e -> new IllegalStateException("Could not obtain the keys", e)) .map(jwkList -> createClaimsSet(parsedToken, jwkList)) .map(set -> createJwt(parsedToken, set)) .map(this::validateJwt) .onErrorMap(e -> !(e instanceof IllegalStateException) && !(e instanceof JwtException), e -> new JwtException("An error occurred while attempting to decode the Jwt: ", e)); } catch (RuntimeException ex) { throw new JwtException("An error occurred while attempting to decode the Jwt: " + ex.getMessage(), ex); } }
.onErrorMap(OAuth2AuthorizationException.class, e -> new OAuth2AuthenticationException(e.getError(), e.getError().toString())) .onErrorMap(JwtException.class, e -> { OAuth2Error invalidIdTokenError = new OAuth2Error(INVALID_ID_TOKEN_ERROR_CODE, e.getMessage(), null); throw new OAuth2AuthenticationException(invalidIdTokenError, invalidIdTokenError.toString(), e); });
private Jwt createJwt(String token, JWT parsedJwt) { Jwt jwt; try { // Verify the signature JWTClaimsSet jwtClaimsSet = this.jwtProcessor.process(parsedJwt, null); Map<String, Object> headers = new LinkedHashMap<>(parsedJwt.getHeader().toJSONObject()); Map<String, Object> claims = this.claimSetConverter.convert(jwtClaimsSet.getClaims()); Instant expiresAt = (Instant) claims.get(JwtClaimNames.EXP); Instant issuedAt = (Instant) claims.get(JwtClaimNames.IAT); jwt = new Jwt(token, issuedAt, expiresAt, headers, claims); } catch (RemoteKeySourceException ex) { if (ex.getCause() instanceof ParseException) { throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed Jwk set")); } else { throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex); } } catch (Exception ex) { if (ex.getCause() instanceof ParseException) { throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed payload")); } else { throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex); } } return jwt; }
private OAuth2AuthenticationException onError(JwtException e) { OAuth2Error invalidRequest = invalidToken(e.getMessage()); return new OAuth2AuthenticationException(invalidRequest, e.getMessage()); }
@Override public Mono<Jwt> decode(String token) throws JwtException { JWT jwt = parse(token); if (jwt instanceof SignedJWT) { return this.decode((SignedJWT) jwt); } throw new JwtException("Unsupported algorithm of " + jwt.getHeader().getAlgorithm()); }
/** * Decode and validate the * <a href="https://tools.ietf.org/html/rfc6750#section-1.2" target="_blank">Bearer Token</a>. * * @param authentication the authentication request object. * * @return A successful authentication * @throws AuthenticationException if authentication failed for some reason */ @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { BearerTokenAuthenticationToken bearer = (BearerTokenAuthenticationToken) authentication; Jwt jwt; try { jwt = this.jwtDecoder.decode(bearer.getToken()); } catch (JwtException failed) { OAuth2Error invalidToken = invalidToken(failed.getMessage()); throw new OAuth2AuthenticationException(invalidToken, invalidToken.getDescription(), failed); } AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt); token.setDetails(bearer.getDetails()); return token; }
/** * Decode and validate the JWT from its compact claims representation format * * @param token the JWT value * @return a validated {@link Jwt} * @throws JwtException */ @Override public Jwt decode(String token) throws JwtException { JWT jwt = parse(token); if (jwt instanceof SignedJWT) { Jwt createdJwt = createJwt(token, jwt); return validateJwt(createdJwt); } throw new JwtException("Unsupported algorithm of " + jwt.getHeader().getAlgorithm()); }
@Test public void authenticateWhenJwtExceptionThenOAuth2AuthenticationException() { BearerTokenAuthenticationToken token = new BearerTokenAuthenticationToken("token-1"); when(this.jwtDecoder.decode(any())).thenReturn(Mono.error(new JwtException("Oops"))); assertThatCode(() -> this.manager.authenticate(token).block()) .isInstanceOf(OAuth2AuthenticationException.class); }
@Test public void authenticateWhenIdTokenValidationErrorThenThrowOAuth2AuthenticationException() { this.exception.expect(OAuth2AuthenticationException.class); this.exception.expectMessage(containsString("[invalid_id_token] ID Token Validation Error")); JwtDecoder jwtDecoder = mock(JwtDecoder.class); when(jwtDecoder.decode(anyString())).thenThrow(new JwtException("ID Token Validation Error")); this.authenticationProvider.setJwtDecoderFactory(registration -> jwtDecoder); this.authenticationProvider.authenticate( new OAuth2LoginAuthenticationToken(this.clientRegistration, this.authorizationExchange)); }
@Test public void authenticateWhenIdTokenValidationErrorThenOAuth2AuthenticationException() { OAuth2AccessTokenResponse accessTokenResponse = OAuth2AccessTokenResponse.withToken("foo") .tokenType(OAuth2AccessToken.TokenType.BEARER) .additionalParameters(Collections.singletonMap(OidcParameterNames.ID_TOKEN, this.idToken.getTokenValue())) .build(); when(this.accessTokenResponseClient.getTokenResponse(any())).thenReturn(Mono.just(accessTokenResponse)); when(this.jwtDecoder.decode(any())).thenThrow(new JwtException("ID Token Validation Error")); this.manager.setJwtDecoderFactory(c -> this.jwtDecoder); assertThatThrownBy(() -> this.manager.authenticate(loginToken()).block()) .isInstanceOf(OAuth2AuthenticationException.class) .hasMessageContaining("[invalid_id_token] ID Token Validation Error"); }
@Test public void authenticateWhenDecoderThrowsIncompatibleErrorMessageThenWrapsWithGenericOne() { BearerTokenAuthenticationToken token = this.authentication(); when(this.jwtDecoder.decode(token.getToken())).thenThrow(new JwtException("with \"invalid\" chars")); assertThatCode(() -> this.provider.authenticate(token)) .isInstanceOf(OAuth2AuthenticationException.class) .hasFieldOrPropertyWithValue( "error.description", "An error occurred while attempting to decode the Jwt: Invalid token"); }
private JWT parse(String token) { try { return JWTParser.parse(token); } catch (Exception ex) { throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex); } }
private JWT parse(String token) { try { return JWTParser.parse(token); } catch (Exception ex) { throw new JwtException("An error occurred while attempting to decode the Jwt: " + ex.getMessage(), ex); } }
private JWTClaimsSet createClaimsSet(JWT parsedToken, List<JWK> jwkList) { try { return this.jwtProcessor.process(parsedToken, new JWKContext(jwkList)); } catch (BadJOSEException | JOSEException e) { throw new JwtException("Failed to validate the token", e); } }