private Mono<List<JWK>> get(JWKSelector jwkSelector, JWKSet jwkSet) { return Mono.defer(() -> { // Run the selector on the JWK set List<JWK> matches = jwkSelector.select(jwkSet); if (!matches.isEmpty()) { // Success return Mono.just(matches); } // Refresh the JWK set if the sought key ID is not in the cached JWK set // Looking for JWK with specific ID? String soughtKeyID = getFirstSpecifiedKeyID(jwkSelector.getMatcher()); if (soughtKeyID == null) { // No key ID specified, return no matches return Mono.just(Collections.emptyList()); } if (jwkSet.getKeyByKeyId(soughtKeyID) != null) { // The key ID exists in the cached JWK set, matching // failed for some other reason, return no matches return Mono.just(Collections.emptyList()); } return Mono.empty(); }); }
/** * Constructs a {@code NimbusJwtDecoderJwkSupport} using the provided parameters. * * @param jwkSetUrl the JSON Web Key (JWK) Set {@code URL} */ public NimbusReactiveJwtDecoder(String jwkSetUrl) { Assert.hasText(jwkSetUrl, "jwkSetUrl cannot be empty"); String jwsAlgorithm = JwsAlgorithms.RS256; JWSAlgorithm algorithm = JWSAlgorithm.parse(jwsAlgorithm); JWKSource jwkSource = new JWKContextJWKSource(); JWSKeySelector<JWKContext> jwsKeySelector = new JWSVerificationKeySelector<>(algorithm, jwkSource); DefaultJWTProcessor<JWKContext> jwtProcessor = new DefaultJWTProcessor<>(); jwtProcessor.setJWSKeySelector(jwsKeySelector); jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {}); this.jwtProcessor = jwtProcessor; this.reactiveJwkSource = new ReactiveRemoteJWKSource(jwkSetUrl); this.jwkSelectorFactory = new JWKSelectorFactory(algorithm); }
@Before public void setup() { this.server = new MockWebServer(); this.source = new ReactiveRemoteJWKSource(this.server.url("/").toString()); this.server.enqueue(new MockResponse().setBody(this.keys)); this.selector = new JWKSelector(this.matcher); }
@Test public void getWhenNoMatchAndNoKeyIdThenEmpty() { when(this.matcher.matches(any())).thenReturn(false); when(this.matcher.getKeyIDs()).thenReturn(Collections.emptySet()); assertThat(this.source.get(this.selector).block()).isEmpty(); }
/** * Constructs a {@code NimbusJwtDecoderJwkSupport} using the provided parameters. * * @param jwkSetUrl the JSON Web Key (JWK) Set {@code URL} */ public NimbusReactiveJwtDecoder(String jwkSetUrl) { Assert.hasText(jwkSetUrl, "jwkSetUrl cannot be empty"); String jwsAlgorithm = JwsAlgorithms.RS256; JWSAlgorithm algorithm = JWSAlgorithm.parse(jwsAlgorithm); JWKSource jwkSource = new JWKContextJWKSource(); JWSKeySelector<JWKContext> jwsKeySelector = new JWSVerificationKeySelector<>(algorithm, jwkSource); DefaultJWTProcessor<JWKContext> jwtProcessor = new DefaultJWTProcessor<>(); jwtProcessor.setJWSKeySelector(jwsKeySelector); jwtProcessor.setJWTClaimsSetVerifier((claims, context) -> {}); this.jwtProcessor = jwtProcessor; this.reactiveJwkSource = new ReactiveRemoteJWKSource(jwkSetUrl); this.jwkSelectorFactory = new JWKSelectorFactory(algorithm); }
private Mono<List<JWK>> get(JWKSelector jwkSelector, JWKSet jwkSet) { return Mono.defer(() -> { // Run the selector on the JWK set List<JWK> matches = jwkSelector.select(jwkSet); if (!matches.isEmpty()) { // Success return Mono.just(matches); } // Refresh the JWK set if the sought key ID is not in the cached JWK set // Looking for JWK with specific ID? String soughtKeyID = getFirstSpecifiedKeyID(jwkSelector.getMatcher()); if (soughtKeyID == null) { // No key ID specified, return no matches return Mono.just(Collections.emptyList()); } if (jwkSet.getKeyByKeyId(soughtKeyID) != null) { // The key ID exists in the cached JWK set, matching // failed for some other reason, return no matches return Mono.just(Collections.emptyList()); } return Mono.empty(); }); }
@Test public void getWhenNoMatchAndKeyIdMatchThenEmpty() { when(this.matcher.matches(any())).thenReturn(false); when(this.matcher.getKeyIDs()).thenReturn(Collections.singleton("7ddf54d3032d1f0d48c3618892ca74c1ac30ad77")); assertThat(this.source.get(this.selector).block()).isEmpty(); } }
@Test public void getWhenNoMatchAndKeyIdNotMatchThenRefreshAndFoundThenFound() { this.server.enqueue(new MockResponse().setBody(this.keys2)); when(this.matcher.matches(any())).thenReturn(false, false, true); when(this.matcher.getKeyIDs()).thenReturn(Collections.singleton("rotated")); List<JWK> keys = this.source.get(this.selector).block(); assertThat(keys).hasSize(1); assertThat(keys.get(0).getKeyID()).isEqualTo("rotated"); }
@Test public void getWhenNoMatchAndKeyIdNotMatchThenRefreshAndNotFoundThenEmpty() { this.server.enqueue(new MockResponse().setBody(this.keys2)); when(this.matcher.matches(any())).thenReturn(false, false, false); when(this.matcher.getKeyIDs()).thenReturn(Collections.singleton("rotated")); List<JWK> keys = this.source.get(this.selector).block(); assertThat(keys).isEmpty(); }
@Test public void getWhenMatchThenCreatesKeys() { when(this.matcher.matches(any())).thenReturn(true); List<JWK> keys = this.source.get(this.selector).block(); assertThat(keys).hasSize(2); JWK key1 = keys.get(0); assertThat(key1.getKeyID()).isEqualTo("1923397381d9574bb873202a90c32b7ceeaed027"); assertThat(key1.getAlgorithm().getName()).isEqualTo("RS256"); assertThat(key1.getKeyType()).isEqualTo(KeyType.RSA); assertThat(key1.getKeyUse()).isEqualTo(KeyUse.SIGNATURE); JWK key2 = keys.get(1); assertThat(key2.getKeyID()).isEqualTo("7ddf54d3032d1f0d48c3618892ca74c1ac30ad77"); assertThat(key2.getAlgorithm().getName()).isEqualTo("RS256"); assertThat(key2.getKeyType()).isEqualTo(KeyType.RSA); assertThat(key2.getKeyUse()).isEqualTo(KeyUse.SIGNATURE); }