Skip to content

Commit 23be7a6

Browse files
authored
Gjør TokenXExchangeKlient retryable og inkluderer cache (#1326)
1 parent 5be8f9f commit 23be7a6

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

felles/oidc/src/main/java/no/nav/vedtak/sikkerhet/oidc/token/impl/TokenXExchangeKlient.java

+45-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
import java.net.URI;
66
import java.net.http.HttpRequest;
77
import java.time.Duration;
8+
import java.util.concurrent.TimeUnit;
9+
10+
import no.nav.vedtak.sikkerhet.kontekst.DefaultRequestKontekstProvider;
11+
import no.nav.vedtak.sikkerhet.kontekst.KontekstProvider;
12+
import no.nav.vedtak.util.LRUCache;
813

914
import org.slf4j.Logger;
1015
import org.slf4j.LoggerFactory;
@@ -19,15 +24,20 @@
1924
public final class TokenXExchangeKlient {
2025

2126
private static final Logger LOG = LoggerFactory.getLogger(TokenXExchangeKlient.class);
27+
private static final KontekstProvider KONTEKST_PROVIDER = new DefaultRequestKontekstProvider();
28+
private static final int RETRIES = 2; // 1 attempt, the n retries
2229

2330
private static TokenXExchangeKlient INSTANCE;
2431

32+
private LRUCache<String, OpenIDToken> obocache;
33+
2534
private final URI tokenEndpoint;
2635

2736

2837
private TokenXExchangeKlient() {
2938
var provider = ConfigProvider.getOpenIDConfiguration(OpenIDProvider.TOKENX);
3039
this.tokenEndpoint = provider.map(OpenIDConfiguration::tokenEndpoint).orElse(null);
40+
this.obocache = new LRUCache<>(2500, TimeUnit.MILLISECONDS.convert(90, TimeUnit.SECONDS));
3141
}
3242

3343
public static synchronized TokenXExchangeKlient instance() {
@@ -41,10 +51,19 @@ public static synchronized TokenXExchangeKlient instance() {
4151

4252
public OpenIDToken exchangeToken(OpenIDToken token, String assertion, String scopes) {
4353
var audience = audience(scopes);
54+
var uid = KONTEKST_PROVIDER.getKontekst().getUid();
55+
var tokenFromCache = getCachedToken(uid, audience);
56+
if (tokenFromCache != null && tokenFromCache.isNotExpired()) {
57+
return tokenFromCache.copy();
58+
}
59+
4460
var response = hentToken(token, assertion, audience);
4561
LOG.debug("TokenX byttet og fikk token av type {} utløper {}", response.token_type(), response.expires_in());
46-
return new OpenIDToken(OpenIDProvider.TOKENX, response.token_type(), new TokenString(response.access_token()), audience,
62+
63+
var newToken = new OpenIDToken(OpenIDProvider.TOKENX, response.token_type(), new TokenString(response.access_token()), audience,
4764
response.expires_in());
65+
putTokenToCache(uid, scopes, newToken);
66+
return newToken.copy();
4867
}
4968

5069
private OidcTokenResponse hentToken(OpenIDToken token, String assertion, String audience) {
@@ -55,15 +74,22 @@ private OidcTokenResponse hentToken(OpenIDToken token, String assertion, String
5574
.uri(tokenEndpoint)
5675
.POST(ofFormData(token, assertion, audience))
5776
.build();
58-
try {
59-
return GeneriskTokenKlient.hentToken(request, null);
60-
} catch (TekniskException e) {
61-
//Vist seg å være litt ustabil
62-
LOG.info("Feiler ved henting av token. Prøver på nytt", e);
63-
return GeneriskTokenKlient.hentToken(request, null);
77+
return hentTokenRetryable(request);
78+
}
79+
80+
public static OidcTokenResponse hentTokenRetryable(HttpRequest request) {
81+
int i = RETRIES;
82+
while (i-- > 0) {
83+
try {
84+
return GeneriskTokenKlient.hentToken(request, null);
85+
} catch (TekniskException e) {
86+
LOG.info("Feilet {}. gang ved henting av token. Prøver på nytt", RETRIES - i, e);
87+
}
6488
}
89+
return GeneriskTokenKlient.hentToken(request, null);
6590
}
6691

92+
6793
private static HttpRequest.BodyPublisher ofFormData(OpenIDToken token, String assertion, String audience) {
6894
var formdata = "grant_type=urn:ietf:params:oauth:grant-type:token-exchange&"
6995
+ "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&"
@@ -80,4 +106,16 @@ private static String audience(String scope) {
80106
.replace("/.default", "")
81107
.replace(".", ":");
82108
}
109+
110+
private OpenIDToken getCachedToken(String uid, String audience) {
111+
return obocache.get(cacheKey(uid, audience));
112+
}
113+
114+
private void putTokenToCache(String uid, String audience, OpenIDToken exchangedToken) {
115+
obocache.put(cacheKey(uid, audience), exchangedToken);
116+
}
117+
118+
private String cacheKey(String uid, String audience) {
119+
return uid + ":::" + audience;
120+
}
83121
}

0 commit comments

Comments
 (0)