From d42968741b52276ab32c3f29bad299fc49f04016 Mon Sep 17 00:00:00 2001 From: MattyA Date: Sun, 24 May 2020 11:11:13 +0100 Subject: [PATCH] Allow for custom rest template --- ...a => JwtDecoderProviderConfiguration.java} | 33 ++++++++++++------- .../security/oauth2/jwt/JwtDecoders.java | 8 +++-- .../oauth2/jwt/ReactiveJwtDecoders.java | 14 ++++++-- ...ReactiveAuthenticationManagerResolver.java | 8 ++++- 4 files changed, 44 insertions(+), 19 deletions(-) rename oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/{JwtDecoderProviderConfigurationUtils.java => JwtDecoderProviderConfiguration.java} (73%) diff --git a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoderProviderConfigurationUtils.java b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoderProviderConfiguration.java similarity index 73% rename from oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoderProviderConfigurationUtils.java rename to oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoderProviderConfiguration.java index 2496abb5b12..cde62b71923 100644 --- a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoderProviderConfigurationUtils.java +++ b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoderProviderConfiguration.java @@ -36,23 +36,32 @@ * @author Rafiullah Hamedy * @since 5.2 */ -class JwtDecoderProviderConfigurationUtils { +public class JwtDecoderProviderConfiguration { private static final String OIDC_METADATA_PATH = "/.well-known/openid-configuration"; private static final String OAUTH_METADATA_PATH = "/.well-known/oauth-authorization-server"; - private static final RestTemplate rest = new RestTemplate(); - private static final ParameterizedTypeReference> typeReference = + private final RestTemplate rest = new RestTemplate(); + private final ParameterizedTypeReference> typeReference = new ParameterizedTypeReference>() {}; - static Map getConfigurationForOidcIssuerLocation(String oidcIssuerLocation) { - return getConfiguration(oidcIssuerLocation, oidc(URI.create(oidcIssuerLocation))); + Map getConfigurationForOidcIssuerLocation(String oidcIssuerLocation) { + return getConfiguration(rest, oidcIssuerLocation, oidc(URI.create(oidcIssuerLocation))); + } + Map getConfigurationForOidcIssuerLocationWithRestTemplate(RestTemplate rest, String oidcIssuerLocation) { + return getConfiguration(rest, oidcIssuerLocation, oidc(URI.create(oidcIssuerLocation))); + } + + Map getConfigurationForIssuerLocation(String issuer) { + URI uri = URI.create(issuer); + return getConfiguration(rest, issuer, oidc(uri), oidcRfc8414(uri), oauth(uri)); } - static Map getConfigurationForIssuerLocation(String issuer) { + Map getConfigurationForIssuerLocationWithRestTemplate(String issuer, RestTemplate rest) + { URI uri = URI.create(issuer); - return getConfiguration(issuer, oidc(uri), oidcRfc8414(uri), oauth(uri)); + return getConfiguration(rest, issuer, oidc(uri), oidcRfc8414(uri), oauth(uri)); } - static void validateIssuer(Map configuration, String issuer) { + void validateIssuer(Map configuration, String issuer) { String metadataIssuer = "(unavailable)"; if (configuration.containsKey("issuer")) { metadataIssuer = configuration.get("issuer").toString(); @@ -63,7 +72,7 @@ static void validateIssuer(Map configuration, String issuer) { } } - private static Map getConfiguration(String issuer, URI... uris) { + private Map getConfiguration(RestTemplate rest, String issuer, URI... uris) { String errorMessage = "Unable to resolve the Configuration with the provided Issuer of " + "\"" + issuer + "\""; for (URI uri : uris) { @@ -90,19 +99,19 @@ private static Map getConfiguration(String issuer, URI... uris) throw new IllegalArgumentException(errorMessage); } - private static URI oidc(URI issuer) { + private URI oidc(URI issuer) { return UriComponentsBuilder.fromUri(issuer) .replacePath(issuer.getPath() + OIDC_METADATA_PATH) .build(Collections.emptyMap()); } - private static URI oidcRfc8414(URI issuer) { + private URI oidcRfc8414(URI issuer) { return UriComponentsBuilder.fromUri(issuer) .replacePath(OIDC_METADATA_PATH + issuer.getPath()) .build(Collections.emptyMap()); } - private static URI oauth(URI issuer) { + private URI oauth(URI issuer) { return UriComponentsBuilder.fromUri(issuer) .replacePath(OAUTH_METADATA_PATH + issuer.getPath()) .build(Collections.emptyMap()); diff --git a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoders.java b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoders.java index 0d2f2331987..9875e7fae9d 100644 --- a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoders.java +++ b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/JwtDecoders.java @@ -34,6 +34,8 @@ */ public final class JwtDecoders { + private final static JwtDecoderProviderConfiguration JWT_DECODER_PROVIDER_CONFIGURATION = new JwtDecoderProviderConfiguration(); + /** * Creates a {@link JwtDecoder} using the provided * Issuer by making an @@ -47,7 +49,7 @@ public final class JwtDecoders { */ public static JwtDecoder fromOidcIssuerLocation(String oidcIssuerLocation) { Assert.hasText(oidcIssuerLocation, "oidcIssuerLocation cannot be empty"); - Map configuration = JwtDecoderProviderConfigurationUtils.getConfigurationForOidcIssuerLocation(oidcIssuerLocation); + Map configuration = new JwtDecoderProviderConfiguration().getConfigurationForOidcIssuerLocation(oidcIssuerLocation); return withProviderConfiguration(configuration, oidcIssuerLocation); } @@ -85,7 +87,7 @@ public static JwtDecoder fromOidcIssuerLocation(String oidcIssuerLocation) { */ public static JwtDecoder fromIssuerLocation(String issuer) { Assert.hasText(issuer, "issuer cannot be empty"); - Map configuration = JwtDecoderProviderConfigurationUtils.getConfigurationForIssuerLocation(issuer); + Map configuration = JWT_DECODER_PROVIDER_CONFIGURATION.getConfigurationForIssuerLocation(issuer); return withProviderConfiguration(configuration, issuer); } @@ -100,7 +102,7 @@ public static JwtDecoder fromIssuerLocation(String issuer) { * @return {@link JwtDecoder} */ private static JwtDecoder withProviderConfiguration(Map configuration, String issuer) { - JwtDecoderProviderConfigurationUtils.validateIssuer(configuration, issuer); + JWT_DECODER_PROVIDER_CONFIGURATION.validateIssuer(configuration, issuer); OAuth2TokenValidator jwtValidator = JwtValidators.createDefaultWithIssuer(issuer); NimbusJwtDecoder jwtDecoder = withJwkSetUri(configuration.get("jwks_uri").toString()).build(); jwtDecoder.setJwtValidator(jwtValidator); diff --git a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.java b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.java index d062b515cfb..ea83e73cb0e 100644 --- a/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.java +++ b/oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/ReactiveJwtDecoders.java @@ -19,6 +19,7 @@ import org.springframework.security.oauth2.core.OAuth2TokenValidator; import org.springframework.util.Assert; +import org.springframework.web.client.RestTemplate; import static org.springframework.security.oauth2.jwt.NimbusReactiveJwtDecoder.withJwkSetUri; @@ -33,6 +34,7 @@ */ public final class ReactiveJwtDecoders { + private static final JwtDecoderProviderConfiguration JWT_DECODER_PROVIDER_CONFIGURATION = new JwtDecoderProviderConfiguration(); /** * Creates a {@link ReactiveJwtDecoder} using the provided * Issuer by making an @@ -46,7 +48,7 @@ public final class ReactiveJwtDecoders { */ public static ReactiveJwtDecoder fromOidcIssuerLocation(String oidcIssuerLocation) { Assert.hasText(oidcIssuerLocation, "oidcIssuerLocation cannot be empty"); - Map configuration = JwtDecoderProviderConfigurationUtils.getConfigurationForOidcIssuerLocation(oidcIssuerLocation); + Map configuration = JWT_DECODER_PROVIDER_CONFIGURATION.getConfigurationForOidcIssuerLocation(oidcIssuerLocation); return withProviderConfiguration(configuration, oidcIssuerLocation); } @@ -84,7 +86,13 @@ public static ReactiveJwtDecoder fromOidcIssuerLocation(String oidcIssuerLocatio */ public static ReactiveJwtDecoder fromIssuerLocation(String issuer) { Assert.hasText(issuer, "issuer cannot be empty"); - Map configuration = JwtDecoderProviderConfigurationUtils.getConfigurationForIssuerLocation(issuer); + Map configuration = JWT_DECODER_PROVIDER_CONFIGURATION.getConfigurationForIssuerLocation(issuer); + return withProviderConfiguration(configuration, issuer); + } + + public static ReactiveJwtDecoder fromIssuerLocation(String issuer, RestTemplate rest) { + Assert.hasText(issuer, "issuer cannot be empty"); + Map configuration = JWT_DECODER_PROVIDER_CONFIGURATION.getConfigurationForIssuerLocation(issuer); return withProviderConfiguration(configuration, issuer); } @@ -99,7 +107,7 @@ public static ReactiveJwtDecoder fromIssuerLocation(String issuer) { * @return {@link ReactiveJwtDecoder} */ private static ReactiveJwtDecoder withProviderConfiguration(Map configuration, String issuer) { - JwtDecoderProviderConfigurationUtils.validateIssuer(configuration, issuer); + JWT_DECODER_PROVIDER_CONFIGURATION.validateIssuer(configuration, issuer); OAuth2TokenValidator jwtValidator = JwtValidators.createDefaultWithIssuer(issuer); NimbusReactiveJwtDecoder jwtDecoder = withJwkSetUri(configuration.get("jwks_uri").toString()).build(); jwtDecoder.setJwtValidator(jwtValidator); diff --git a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolver.java b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolver.java index c2f415378b7..de110da22f9 100644 --- a/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolver.java +++ b/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/authentication/JwtIssuerReactiveAuthenticationManagerResolver.java @@ -24,6 +24,7 @@ import java.util.function.Predicate; import com.nimbusds.jwt.JWTParser; +import org.springframework.web.client.RestTemplate; import reactor.core.publisher.Mono; import reactor.core.scheduler.Schedulers; @@ -62,6 +63,7 @@ public final class JwtIssuerReactiveAuthenticationManagerResolver private final ReactiveAuthenticationManagerResolver issuerAuthenticationManagerResolver; private final Converter> issuerConverter = new JwtClaimIssuerConverter(); + private RestTemplate rest = new RestTemplate(); /** * Construct a {@link JwtIssuerReactiveAuthenticationManagerResolver} using the provided parameters @@ -72,6 +74,10 @@ public JwtIssuerReactiveAuthenticationManagerResolver(String... trustedIssuers) this(Arrays.asList(trustedIssuers)); } + public void setRest(RestTemplate rest) { + this.rest = rest; + } + /** * Construct a {@link JwtIssuerReactiveAuthenticationManagerResolver} using the provided parameters * @@ -167,7 +173,7 @@ public Mono resolve(String issuer) { } return this.authenticationManagers.computeIfAbsent(issuer, k -> Mono.fromCallable(() -> - new JwtReactiveAuthenticationManager(ReactiveJwtDecoders.fromIssuerLocation(k)) + new JwtReactiveAuthenticationManager(ReactiveJwtDecoders.fromIssuerLocation(k, rest)) ) .subscribeOn(Schedulers.boundedElastic()) .cache());