|
@@ -145,19 +145,15 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
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());
|
|
|
-
|
|
|
return Jwt.withTokenValue(token).headers((h) -> h.putAll(headers)).claims((c) -> c.putAll(claims)).build();
|
|
|
}
|
|
|
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);
|
|
|
- }
|
|
|
+ throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
|
|
|
}
|
|
|
catch (JOSEException ex) {
|
|
|
throw new JwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
|
|
@@ -166,9 +162,7 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
if (ex.getCause() instanceof ParseException) {
|
|
|
throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, "Malformed payload"));
|
|
|
}
|
|
|
- else {
|
|
|
- throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
|
|
|
- }
|
|
|
+ throw new BadJwtException(String.format(DECODING_ERROR_MESSAGE_TEMPLATE, ex.getMessage()), ex);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -176,20 +170,21 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
OAuth2TokenValidatorResult result = this.jwtValidator.validate(jwt);
|
|
|
if (result.hasErrors()) {
|
|
|
Collection<OAuth2Error> errors = result.getErrors();
|
|
|
- String validationErrorString = "Unable to validate Jwt";
|
|
|
- for (OAuth2Error oAuth2Error : errors) {
|
|
|
- if (!StringUtils.isEmpty(oAuth2Error.getDescription())) {
|
|
|
- validationErrorString = String.format(DECODING_ERROR_MESSAGE_TEMPLATE,
|
|
|
- oAuth2Error.getDescription());
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- throw new JwtValidationException(validationErrorString, result.getErrors());
|
|
|
+ String validationErrorString = getJwtValidationExceptionMessage(errors);
|
|
|
+ throw new JwtValidationException(validationErrorString, errors);
|
|
|
}
|
|
|
-
|
|
|
return jwt;
|
|
|
}
|
|
|
|
|
|
+ private String getJwtValidationExceptionMessage(Collection<OAuth2Error> errors) {
|
|
|
+ for (OAuth2Error oAuth2Error : errors) {
|
|
|
+ if (!StringUtils.isEmpty(oAuth2Error.getDescription())) {
|
|
|
+ return String.format(DECODING_ERROR_MESSAGE_TEMPLATE, oAuth2Error.getDescription());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return "Unable to validate Jwt";
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Use the given <a href="https://tools.ietf.org/html/rfc7517#section-5">JWK Set</a>
|
|
|
* uri.
|
|
@@ -316,14 +311,12 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
if (this.signatureAlgorithms.isEmpty()) {
|
|
|
return new JWSVerificationKeySelector<>(JWSAlgorithm.RS256, jwkSource);
|
|
|
}
|
|
|
- else {
|
|
|
- Set<JWSAlgorithm> jwsAlgorithms = new HashSet<>();
|
|
|
- for (SignatureAlgorithm signatureAlgorithm : this.signatureAlgorithms) {
|
|
|
- JWSAlgorithm jwsAlgorithm = JWSAlgorithm.parse(signatureAlgorithm.getName());
|
|
|
- jwsAlgorithms.add(jwsAlgorithm);
|
|
|
- }
|
|
|
- return new JWSVerificationKeySelector<>(jwsAlgorithms, jwkSource);
|
|
|
+ Set<JWSAlgorithm> jwsAlgorithms = new HashSet<>();
|
|
|
+ for (SignatureAlgorithm signatureAlgorithm : this.signatureAlgorithms) {
|
|
|
+ JWSAlgorithm jwsAlgorithm = JWSAlgorithm.parse(signatureAlgorithm.getName());
|
|
|
+ jwsAlgorithms.add(jwsAlgorithm);
|
|
|
}
|
|
|
+ return new JWSVerificationKeySelector<>(jwsAlgorithms, jwkSource);
|
|
|
}
|
|
|
|
|
|
JWKSource<SecurityContext> jwkSource(ResourceRetriever jwkSetRetriever) {
|
|
@@ -339,13 +332,10 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
JWKSource<SecurityContext> jwkSource = jwkSource(jwkSetRetriever);
|
|
|
ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
|
|
|
jwtProcessor.setJWSKeySelector(jwsKeySelector(jwkSource));
|
|
|
-
|
|
|
// Spring Security validates the claim set independent from Nimbus
|
|
|
jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {
|
|
|
});
|
|
|
-
|
|
|
this.jwtProcessorCustomizer.accept(jwtProcessor);
|
|
|
-
|
|
|
return jwtProcessor;
|
|
|
}
|
|
|
|
|
@@ -397,10 +387,10 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
|
|
|
@Override
|
|
|
public Resource retrieveResource(URL url) throws IOException {
|
|
|
- String jwkSet;
|
|
|
try {
|
|
|
- jwkSet = this.cache.get(url.toString(),
|
|
|
+ String jwkSet = this.cache.get(url.toString(),
|
|
|
() -> this.resourceRetriever.retrieveResource(url).getContent());
|
|
|
+ return new Resource(jwkSet, "UTF-8");
|
|
|
}
|
|
|
catch (Cache.ValueRetrievalException ex) {
|
|
|
Throwable thrownByValueLoader = ex.getCause();
|
|
@@ -412,8 +402,6 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
catch (Exception ex) {
|
|
|
throw new IOException(ex);
|
|
|
}
|
|
|
-
|
|
|
- return new Resource(jwkSet, "UTF-8");
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -433,21 +421,21 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
public Resource retrieveResource(URL url) throws IOException {
|
|
|
HttpHeaders headers = new HttpHeaders();
|
|
|
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON, APPLICATION_JWK_SET_JSON));
|
|
|
+ ResponseEntity<String> response = getResponse(url, headers);
|
|
|
+ if (response.getStatusCodeValue() != 200) {
|
|
|
+ throw new IOException(response.toString());
|
|
|
+ }
|
|
|
+ return new Resource(response.getBody(), "UTF-8");
|
|
|
+ }
|
|
|
|
|
|
- ResponseEntity<String> response;
|
|
|
+ private ResponseEntity<String> getResponse(URL url, HttpHeaders headers) throws IOException {
|
|
|
try {
|
|
|
RequestEntity<Void> request = new RequestEntity<>(headers, HttpMethod.GET, url.toURI());
|
|
|
- response = this.restOperations.exchange(request, String.class);
|
|
|
+ return this.restOperations.exchange(request, String.class);
|
|
|
}
|
|
|
catch (Exception ex) {
|
|
|
throw new IOException(ex);
|
|
|
}
|
|
|
-
|
|
|
- if (response.getStatusCodeValue() != 200) {
|
|
|
- throw new IOException(response.toString());
|
|
|
- }
|
|
|
-
|
|
|
- return new Resource(response.getBody(), "UTF-8");
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -506,22 +494,16 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
}
|
|
|
|
|
|
JWTProcessor<SecurityContext> processor() {
|
|
|
- if (!JWSAlgorithm.Family.RSA.contains(this.jwsAlgorithm)) {
|
|
|
- throw new IllegalStateException(
|
|
|
- "The provided key is of type RSA; " + "however the signature algorithm is of some other type: "
|
|
|
- + this.jwsAlgorithm + ". Please indicate one of RS256, RS384, or RS512.");
|
|
|
- }
|
|
|
-
|
|
|
+ Assert.state(JWSAlgorithm.Family.RSA.contains(this.jwsAlgorithm),
|
|
|
+ () -> "The provided key is of type RSA; however the signature algorithm is of some other type: "
|
|
|
+ + this.jwsAlgorithm + ". Please indicate one of RS256, RS384, or RS512.");
|
|
|
JWSKeySelector<SecurityContext> jwsKeySelector = new SingleKeyJWSKeySelector<>(this.jwsAlgorithm, this.key);
|
|
|
DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
|
|
|
jwtProcessor.setJWSKeySelector(jwsKeySelector);
|
|
|
-
|
|
|
// Spring Security validates the claim set independent from Nimbus
|
|
|
jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {
|
|
|
});
|
|
|
-
|
|
|
this.jwtProcessorCustomizer.accept(jwtProcessor);
|
|
|
-
|
|
|
return jwtProcessor;
|
|
|
}
|
|
|
|
|
@@ -599,13 +581,10 @@ public final class NimbusJwtDecoder implements JwtDecoder {
|
|
|
this.secretKey);
|
|
|
DefaultJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
|
|
|
jwtProcessor.setJWSKeySelector(jwsKeySelector);
|
|
|
-
|
|
|
// Spring Security validates the claim set independent from Nimbus
|
|
|
jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {
|
|
|
});
|
|
|
-
|
|
|
this.jwtProcessorCustomizer.accept(jwtProcessor);
|
|
|
-
|
|
|
return jwtProcessor;
|
|
|
}
|
|
|
|