|
@@ -15,34 +15,16 @@
|
|
|
*/
|
|
|
package org.springframework.security.oauth2.jwt;
|
|
|
|
|
|
-import java.io.IOException;
|
|
|
-import java.net.MalformedURLException;
|
|
|
-import java.net.URL;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Map;
|
|
|
|
|
|
-import com.nimbusds.jose.JWSAlgorithm;
|
|
|
-import com.nimbusds.jose.jwk.source.JWKSource;
|
|
|
-import com.nimbusds.jose.jwk.source.RemoteJWKSet;
|
|
|
-import com.nimbusds.jose.proc.JWSKeySelector;
|
|
|
-import com.nimbusds.jose.proc.JWSVerificationKeySelector;
|
|
|
-import com.nimbusds.jose.proc.SecurityContext;
|
|
|
-import com.nimbusds.jose.util.Resource;
|
|
|
-import com.nimbusds.jose.util.ResourceRetriever;
|
|
|
-import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
|
|
|
-import com.nimbusds.jwt.proc.DefaultJWTProcessor;
|
|
|
-
|
|
|
import org.springframework.core.convert.converter.Converter;
|
|
|
-import org.springframework.http.HttpHeaders;
|
|
|
-import org.springframework.http.HttpMethod;
|
|
|
-import org.springframework.http.MediaType;
|
|
|
-import org.springframework.http.RequestEntity;
|
|
|
-import org.springframework.http.ResponseEntity;
|
|
|
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
|
|
import org.springframework.security.oauth2.jose.jws.JwsAlgorithms;
|
|
|
import org.springframework.util.Assert;
|
|
|
import org.springframework.web.client.RestOperations;
|
|
|
-import org.springframework.web.client.RestTemplate;
|
|
|
+
|
|
|
+import static org.springframework.security.oauth2.jwt.JwtProcessors.withJwkSetUri;
|
|
|
|
|
|
/**
|
|
|
* An implementation of a {@link JwtDecoder} that "decodes" a
|
|
@@ -53,7 +35,7 @@ import org.springframework.web.client.RestTemplate;
|
|
|
* <p>
|
|
|
* <b>NOTE:</b> This implementation uses the Nimbus JOSE + JWT SDK internally.
|
|
|
*
|
|
|
- * @deprecated Use {@link NimbusJwtDecoder} instead
|
|
|
+ * @deprecated Use {@link NimbusJwtDecoder} or {@link JwtDecoders} instead
|
|
|
*
|
|
|
* @author Joe Grandja
|
|
|
* @author Josh Cummings
|
|
@@ -67,8 +49,10 @@ import org.springframework.web.client.RestTemplate;
|
|
|
*/
|
|
|
@Deprecated
|
|
|
public final class NimbusJwtDecoderJwkSupport implements JwtDecoder {
|
|
|
- private final JWSAlgorithm jwsAlgorithm;
|
|
|
- private final RestOperationsResourceRetriever jwkSetRetriever = new RestOperationsResourceRetriever();
|
|
|
+ private JwtProcessors.JwkSetUriJwtProcessorBuilder jwtProcessorBuilder;
|
|
|
+ private OAuth2TokenValidator<Jwt> jwtValidator = JwtValidators.createDefault();
|
|
|
+ private Converter<Map<String, Object>, Map<String, Object>> claimSetConverter =
|
|
|
+ MappedJwtClaimSetConverter.withDefaults(Collections.emptyMap());
|
|
|
|
|
|
private NimbusJwtDecoder delegate;
|
|
|
|
|
@@ -90,22 +74,16 @@ public final class NimbusJwtDecoderJwkSupport implements JwtDecoder {
|
|
|
public NimbusJwtDecoderJwkSupport(String jwkSetUrl, String jwsAlgorithm) {
|
|
|
Assert.hasText(jwkSetUrl, "jwkSetUrl cannot be empty");
|
|
|
Assert.hasText(jwsAlgorithm, "jwsAlgorithm cannot be empty");
|
|
|
- JWKSource jwkSource;
|
|
|
- try {
|
|
|
- jwkSource = new RemoteJWKSet(new URL(jwkSetUrl), this.jwkSetRetriever);
|
|
|
- } catch (MalformedURLException ex) {
|
|
|
- throw new IllegalArgumentException("Invalid JWK Set URL \"" + jwkSetUrl + "\" : " + ex.getMessage(), ex);
|
|
|
- }
|
|
|
- this.jwsAlgorithm = JWSAlgorithm.parse(jwsAlgorithm);
|
|
|
- JWSKeySelector<SecurityContext> jwsKeySelector =
|
|
|
- new JWSVerificationKeySelector<>(this.jwsAlgorithm, jwkSource);
|
|
|
- ConfigurableJWTProcessor<SecurityContext> jwtProcessor = new DefaultJWTProcessor<>();
|
|
|
- jwtProcessor.setJWSKeySelector(jwsKeySelector);
|
|
|
|
|
|
- // Spring Security validates the claim set independent from Nimbus
|
|
|
- jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {});
|
|
|
+ this.jwtProcessorBuilder = withJwkSetUri(jwkSetUrl).jwsAlgorithm(jwsAlgorithm);
|
|
|
+ this.delegate = makeDelegate();
|
|
|
+ }
|
|
|
|
|
|
- this.delegate = new NimbusJwtDecoder(jwtProcessor);
|
|
|
+ private NimbusJwtDecoder makeDelegate() {
|
|
|
+ NimbusJwtDecoder delegate = new NimbusJwtDecoder(this.jwtProcessorBuilder.build());
|
|
|
+ delegate.setClaimSetConverter(this.claimSetConverter);
|
|
|
+ delegate.setJwtValidator(this.jwtValidator);
|
|
|
+ return delegate;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -120,6 +98,7 @@ public final class NimbusJwtDecoderJwkSupport implements JwtDecoder {
|
|
|
*/
|
|
|
public void setJwtValidator(OAuth2TokenValidator<Jwt> jwtValidator) {
|
|
|
Assert.notNull(jwtValidator, "jwtValidator cannot be null");
|
|
|
+ this.jwtValidator = jwtValidator;
|
|
|
this.delegate.setJwtValidator(jwtValidator);
|
|
|
}
|
|
|
|
|
@@ -130,6 +109,7 @@ public final class NimbusJwtDecoderJwkSupport implements JwtDecoder {
|
|
|
*/
|
|
|
public final void setClaimSetConverter(Converter<Map<String, Object>, Map<String, Object>> claimSetConverter) {
|
|
|
Assert.notNull(claimSetConverter, "claimSetConverter cannot be null");
|
|
|
+ this.claimSetConverter = claimSetConverter;
|
|
|
this.delegate.setClaimSetConverter(claimSetConverter);
|
|
|
}
|
|
|
|
|
@@ -141,30 +121,7 @@ public final class NimbusJwtDecoderJwkSupport implements JwtDecoder {
|
|
|
*/
|
|
|
public final void setRestOperations(RestOperations restOperations) {
|
|
|
Assert.notNull(restOperations, "restOperations cannot be null");
|
|
|
- this.jwkSetRetriever.restOperations = restOperations;
|
|
|
- }
|
|
|
-
|
|
|
- private static class RestOperationsResourceRetriever implements ResourceRetriever {
|
|
|
- private RestOperations restOperations = new RestTemplate();
|
|
|
-
|
|
|
- @Override
|
|
|
- public Resource retrieveResource(URL url) throws IOException {
|
|
|
- HttpHeaders headers = new HttpHeaders();
|
|
|
- headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
|
|
|
-
|
|
|
- ResponseEntity<String> response;
|
|
|
- try {
|
|
|
- RequestEntity<Void> request = new RequestEntity<>(headers, HttpMethod.GET, url.toURI());
|
|
|
- response = 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");
|
|
|
- }
|
|
|
+ this.jwtProcessorBuilder = this.jwtProcessorBuilder.restOperations(restOperations);
|
|
|
+ this.delegate = makeDelegate();
|
|
|
}
|
|
|
}
|