/** * Configures a {@link ReactiveJwtDecoder} that leverages the provided {@link RSAPublicKey} * * @param publicKey the public key to use. * @return the {@code JwtSpec} for additional configuration */ public JwtSpec publicKey(RSAPublicKey publicKey) { this.jwtDecoder = new NimbusReactiveJwtDecoder(publicKey); return this; }
/** * Configures a {@link ReactiveJwtDecoder} using * <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> URL * @param jwkSetUri the URL to use. * @return the {@code JwtSpec} for additional configuration */ public JwtSpec jwkSetUri(String jwkSetUri) { this.jwtDecoder = new NimbusReactiveJwtDecoder(jwkSetUri); return this; }
/** * Creates a {@link ReactiveJwtDecoder} using the provided * <a href="http://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier">Issuer</a> by making an * <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest">OpenID Provider * Configuration Request</a> and using the values in the * <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse">OpenID * Provider Configuration Response</a> to initialize the {@link ReactiveJwtDecoder}. * * @param oidcIssuerLocation the <a href="http://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier">Issuer</a> * @return a {@link ReactiveJwtDecoder} that was initialized by the OpenID Provider Configuration. */ public static ReactiveJwtDecoder fromOidcIssuerLocation(String oidcIssuerLocation) { Map<String, Object> openidConfiguration = getOpenidConfiguration(oidcIssuerLocation); String metadataIssuer = "(unavailable)"; if (openidConfiguration.containsKey("issuer")) { metadataIssuer = openidConfiguration.get("issuer").toString(); } if (!oidcIssuerLocation.equals(metadataIssuer)) { throw new IllegalStateException("The Issuer \"" + metadataIssuer + "\" provided in the OpenID Configuration " + "did not match the requested issuer \"" + oidcIssuerLocation + "\""); } OAuth2TokenValidator<Jwt> jwtValidator = JwtValidators.createDefaultWithIssuer(oidcIssuerLocation); NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(openidConfiguration.get("jwks_uri").toString()); jwtDecoder.setJwtValidator(jwtValidator); return jwtDecoder; }
@Test public void decodeWhenRSAPublicKeyThenSuccess() throws Exception { byte[] bytes = Base64.getDecoder().decode("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqL48v1clgFw+Evm145pmh8nRYiNt72Gupsshn7Qs8dxEydCRp1DPOV/PahPk1y2nvldBNIhfNL13JOAiJ6BTiF+2ICuICAhDArLMnTH61oL1Hepq8W1xpa9gxsnL1P51thvfmiiT4RTW57koy4xIWmIp8ZXXfYgdH2uHJ9R0CQBuYKe7nEOObjxCFWC8S30huOfW2cYtv0iB23h6w5z2fDLjddX6v/FXM7ktcokgpm3/XmvT/+bL6/GGwz9k6kJOyMTubecr+WT//le8ikY66zlplYXRQh6roFfFCL21Pt8xN5zrk+0AMZUnmi8F2S2ztSBmAVJ7H71ELXsURBVZpwIDAQAB"); RSAPublicKey publicKey = (RSAPublicKey) KeyFactory.getInstance("RSA") .generatePublic(new X509EncodedKeySpec(bytes)); this.decoder = new NimbusReactiveJwtDecoder(publicKey); String noKeyId = "eyJhbGciOiJSUzI1NiJ9.eyJzY29wZSI6IiIsImV4cCI6OTIyMzM3MjAwNjA5NjM3NX0.hNVuHSUkxdLZrDfqdmKcOi0ggmNaDuB4ZPxPtJl1gwBiXzIGN6Hwl24O2BfBZiHFKUTQDs4_RvzD71mEG3DvUrcKmdYWqIB1l8KNmxQLUDG-cAPIpJmRJgCh50tf8OhOE_Cb9E1HcsOUb47kT9iz-VayNBcmo6BmyZLdEGhsdGBrc3Mkz2dd_0PF38I2Hf_cuSjn9gBjFGtiPEXJvob3PEjVTSx_zvodT8D9p3An1R3YBZf5JSd1cQisrXgDX2k1Jmf7UKKWzgfyCgnEtRWWbsUdPqo3rSEY9GDC1iSQXsFTTC1FT_JJDkwzGf011fsU5O_Ko28TARibmKTCxAKNRQ"; assertThatCode(() -> this.decoder.decode(noKeyId).block()) .doesNotThrowAnyException(); }
@Override public ReactiveJwtDecoder createDecoder(ClientRegistration clientRegistration) { Assert.notNull(clientRegistration, "clientRegistration cannot be null"); return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), key -> { if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) { OAuth2Error oauth2Error = new OAuth2Error( MISSING_SIGNATURE_VERIFIER_ERROR_CODE, "Failed to find a Signature Verifier for Client Registration: '" + clientRegistration.getRegistrationId() + "'. Check to ensure you have configured the JwkSet URI.", null ); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); } NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder( clientRegistration.getProviderDetails().getJwkSetUri()); OAuth2TokenValidator<Jwt> jwtValidator = this.jwtValidatorFactory.apply(clientRegistration); jwtDecoder.setJwtValidator(jwtValidator); return jwtDecoder; }); }
@Test public void decodeWhenInvalidJwkSetUrlThenFail() { this.decoder = new NimbusReactiveJwtDecoder("http://localhost:1280/certs"); assertThatCode(() -> this.decoder.decode(this.messageReadToken).block()) .isInstanceOf(IllegalStateException.class); }
@Test public void decodeWhenInvalidUrl() { this.decoder = new NimbusReactiveJwtDecoder("https://s"); assertThatCode(() -> this.decoder.decode(this.messageReadToken).block()) .isInstanceOf(IllegalStateException.class) .hasCauseInstanceOf(UnknownHostException.class); }
/** * Configures a {@link ReactiveJwtDecoder} using * <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> URL * @param jwkSetUri the URL to use. * @return the {@code JwtSpec} for additional configuration */ public JwtSpec jwkSetUri(String jwkSetUri) { this.jwtDecoder = new NimbusReactiveJwtDecoder(jwkSetUri); return this; }
@Before public void setup() throws Exception { this.server = new MockWebServer(); this.server.start(); this.server.enqueue(new MockResponse().setBody(jwkSet)); this.decoder = new NimbusReactiveJwtDecoder(this.server.url("/certs").toString()); }
/** * Configures a {@link ReactiveJwtDecoder} that leverages the provided {@link RSAPublicKey} * * @param publicKey the public key to use. * @return the {@code JwtSpec} for additional configuration */ public JwtSpec publicKey(RSAPublicKey publicKey) { this.jwtDecoder = new NimbusReactiveJwtDecoder(publicKey); return this; }
/** * Configures a {@link ReactiveJwtDecoder} that leverages the provided {@link RSAPublicKey} * * @param publicKey the public key to use. * @return the {@code JwtSpec} for additional configuration */ public JwtSpec publicKey(RSAPublicKey publicKey) { this.jwtDecoder = new NimbusReactiveJwtDecoder(publicKey); return this; }
/** * Configures a {@link ReactiveJwtDecoder} using * <a target="_blank" href="https://tools.ietf.org/html/rfc7517">JSON Web Key (JWK)</a> URL * @param jwkSetUri the URL to use. * @return the {@code JwtSpec} for additional configuration */ public JwtSpec jwkSetUri(String jwkSetUri) { this.jwtDecoder = new NimbusReactiveJwtDecoder(jwkSetUri); return this; }
/** * Creates a {@link ReactiveJwtDecoder} using the provided * <a href="http://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier">Issuer</a> by making an * <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationRequest">OpenID Provider * Configuration Request</a> and using the values in the * <a href="https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse">OpenID * Provider Configuration Response</a> to initialize the {@link ReactiveJwtDecoder}. * * @param oidcIssuerLocation the <a href="http://openid.net/specs/openid-connect-core-1_0.html#IssuerIdentifier">Issuer</a> * @return a {@link ReactiveJwtDecoder} that was initialized by the OpenID Provider Configuration. */ public static ReactiveJwtDecoder fromOidcIssuerLocation(String oidcIssuerLocation) { Map<String, Object> openidConfiguration = getOpenidConfiguration(oidcIssuerLocation); String metadataIssuer = "(unavailable)"; if (openidConfiguration.containsKey("issuer")) { metadataIssuer = openidConfiguration.get("issuer").toString(); } if (!oidcIssuerLocation.equals(metadataIssuer)) { throw new IllegalStateException("The Issuer \"" + metadataIssuer + "\" provided in the OpenID Configuration " + "did not match the requested issuer \"" + oidcIssuerLocation + "\""); } OAuth2TokenValidator<Jwt> jwtValidator = JwtValidators.createDefaultWithIssuer(oidcIssuerLocation); NimbusReactiveJwtDecoder jwtDecoder = new NimbusReactiveJwtDecoder(openidConfiguration.get("jwks_uri").toString()); jwtDecoder.setJwtValidator(jwtValidator); return jwtDecoder; }
@Override public ReactiveJwtDecoder apply(ClientRegistration clientRegistration) { ReactiveJwtDecoder jwtDecoder = this.jwtDecoders.get(clientRegistration.getRegistrationId()); if (jwtDecoder == null) { if (!StringUtils.hasText(clientRegistration.getProviderDetails().getJwkSetUri())) { OAuth2Error oauth2Error = new OAuth2Error( MISSING_SIGNATURE_VERIFIER_ERROR_CODE, "Failed to find a Signature Verifier for Client Registration: '" + clientRegistration.getRegistrationId() + "'. Check to ensure you have configured the JwkSet URI.", null ); throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString()); } jwtDecoder = new NimbusReactiveJwtDecoder(clientRegistration.getProviderDetails().getJwkSetUri()); this.jwtDecoders.put(clientRegistration.getRegistrationId(), jwtDecoder); } return jwtDecoder; } }