|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2019 the original author or authors. |
| 2 | + * Copyright 2002-2023 the original author or authors. |
3 | 3 | *
|
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
5 | 5 | * you may not use this file except in compliance with the License.
|
@@ -43,23 +43,34 @@ class ReactiveRemoteJWKSource implements ReactiveJWKSource {
|
43 | 43 | */
|
44 | 44 | private final AtomicReference<Mono<JWKSet>> cachedJWKSet = new AtomicReference<>(Mono.empty());
|
45 | 45 |
|
| 46 | + /** |
| 47 | + * The cached JWK set URL. |
| 48 | + */ |
| 49 | + private final AtomicReference<String> cachedJwkSetUrl = new AtomicReference<>(); |
| 50 | + |
46 | 51 | private WebClient webClient = WebClient.create();
|
47 | 52 |
|
48 |
| - private final String jwkSetURL; |
| 53 | + private final Mono<String> jwkSetUrlProvider; |
49 | 54 |
|
50 | 55 | ReactiveRemoteJWKSource(String jwkSetURL) {
|
51 | 56 | Assert.hasText(jwkSetURL, "jwkSetURL cannot be empty");
|
52 |
| - this.jwkSetURL = jwkSetURL; |
| 57 | + this.jwkSetUrlProvider = Mono.just(jwkSetURL); |
| 58 | + } |
| 59 | + |
| 60 | + ReactiveRemoteJWKSource(Mono<String> jwkSetUrlProvider) { |
| 61 | + Assert.notNull(jwkSetUrlProvider, "jwkSetUrlProvider cannot be null"); |
| 62 | + this.jwkSetUrlProvider = Mono.fromCallable(this.cachedJwkSetUrl::get) |
| 63 | + .switchIfEmpty(Mono.defer(() -> jwkSetUrlProvider.doOnNext(this.cachedJwkSetUrl::set))); |
53 | 64 | }
|
54 | 65 |
|
55 | 66 | @Override
|
56 | 67 | public Mono<List<JWK>> get(JWKSelector jwkSelector) {
|
57 | 68 | // @formatter:off
|
58 | 69 | return this.cachedJWKSet.get()
|
59 |
| - .switchIfEmpty(Mono.defer(() -> getJWKSet())) |
| 70 | + .switchIfEmpty(Mono.defer(this::getJWKSet)) |
60 | 71 | .flatMap((jwkSet) -> get(jwkSelector, jwkSet))
|
61 | 72 | .switchIfEmpty(Mono.defer(() -> getJWKSet()
|
62 |
| - .map((jwkSet) -> jwkSelector.select(jwkSet))) |
| 73 | + .map(jwkSelector::select)) |
63 | 74 | );
|
64 | 75 | // @formatter:on
|
65 | 76 | }
|
@@ -95,13 +106,15 @@ private Mono<List<JWK>> get(JWKSelector jwkSelector, JWKSet jwkSet) {
|
95 | 106 | */
|
96 | 107 | private Mono<JWKSet> getJWKSet() {
|
97 | 108 | // @formatter:off
|
98 |
| - return this.webClient.get() |
99 |
| - .uri(this.jwkSetURL) |
100 |
| - .retrieve() |
101 |
| - .bodyToMono(String.class) |
| 109 | + return this.jwkSetUrlProvider |
| 110 | + .flatMap((jwkSetURL) -> this.webClient.get() |
| 111 | + .uri(jwkSetURL) |
| 112 | + .retrieve() |
| 113 | + .bodyToMono(String.class) |
| 114 | + ) |
102 | 115 | .map(this::parse)
|
103 | 116 | .doOnNext((jwkSet) -> this.cachedJWKSet
|
104 |
| - .set(Mono.just(jwkSet)) |
| 117 | + .set(Mono.just(jwkSet)) |
105 | 118 | )
|
106 | 119 | .cache();
|
107 | 120 | // @formatter:on
|
|
0 commit comments