Skip to content

Commit

Permalink
Obo-cache, standard lokal/vtp override, endret noen tokenflows (#1186)
Browse files Browse the repository at this point in the history
* Obo-cache, standard lokal/vtp override, endret noen tokenflows

* Mer debug og null-safety
  • Loading branch information
jolarsen authored Sep 22, 2022
1 parent b387291 commit 84d28a5
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 15 deletions.
4 changes: 4 additions & 0 deletions felles/oidc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-klient</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-util</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger</groupId>
<artifactId>konfig</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,11 @@ public OpenIDToken(OpenIDProvider provider,
String scope,
TokenString refresh,
Integer expireIn) {
this(provider, tokenType, primary, scope, refresh,
System.currentTimeMillis() + (MILLIS * (expireIn > LONGLIFE ? expireIn - BUFFER : expireIn)));
this(provider, tokenType, primary, scope, refresh, expireAtFromExpireIn(expireIn));
}

public boolean isExpired() {
return System.currentTimeMillis() > expiresAtMillis;
public boolean isNotExpired() {
return System.currentTimeMillis() < expiresAtMillis;
}

public LocalDateTime expiresAt() {
Expand All @@ -69,4 +68,8 @@ public String toString() {
", expiresAt=" + expiresAt() +
'}';
}

private static long expireAtFromExpireIn(Integer expireIn) {
return System.currentTimeMillis() + (MILLIS * (Optional.ofNullable(expireIn).map(e -> e > LONGLIFE ? expireIn - BUFFER : expireIn).orElse(0)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -16,25 +17,30 @@
import no.nav.vedtak.sikkerhet.oidc.config.OpenIDProvider;
import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken;
import no.nav.vedtak.sikkerhet.oidc.token.TokenString;
import no.nav.vedtak.util.LRUCache;

public class AzureBrukerTokenKlient {

private static final Logger LOG = LoggerFactory.getLogger(AzureBrukerTokenKlient.class);

private static volatile AzureBrukerTokenKlient INSTANCE; // NOSONAR

private LRUCache<String, OpenIDToken> obocache;

private final URI tokenEndpoint;
private final String clientId;
private final String clientSecret;
private final URI azureProxy;


public AzureBrukerTokenKlient() {
private AzureBrukerTokenKlient() {
var provider = ConfigProvider.getOpenIDConfiguration(OpenIDProvider.AZUREAD).orElseThrow();
this.tokenEndpoint = provider.tokenEndpoint();
this.azureProxy = provider.proxy();
this.clientId = provider.clientId();
this.clientSecret = provider.clientSecret();
// Initiell size. Ser ut som OBO-tokens i dev har varihet på 4100-4600 s.
this.obocache = new LRUCache<>(1500, TimeUnit.MILLISECONDS.convert(3599, TimeUnit.SECONDS));
}

public static synchronized AzureBrukerTokenKlient instance() {
Expand Down Expand Up @@ -82,7 +88,10 @@ public Optional<OpenIDToken> refreshIdToken(OpenIDToken expiredToken, String sco
}

public OpenIDToken oboExchangeToken(OpenIDToken incomingToken, String scopes) {
// TODO: vurder caching av incoming+scopes -> exchanged
var tokenFromCache = getCachedToken(incomingToken, scopes);
if (tokenFromCache != null && tokenFromCache.isNotExpired()) {
return tokenFromCache.copy();
}
var data = "client_id=" + clientId +
"&scope=" + URLEncoder.encode(scopes, StandardCharsets.UTF_8) +
"&assertion=" + incomingToken.token() +
Expand All @@ -92,8 +101,13 @@ public OpenIDToken oboExchangeToken(OpenIDToken incomingToken, String scopes) {
var request = lagRequest(data);
var response = GeneriskTokenKlient.hentToken(request, azureProxy);
LOG.info("AzureBruker hentet og fikk token av type {} utløper {}", response.token_type(), response.expires_in());
return new OpenIDToken(OpenIDProvider.AZUREAD, response.token_type(), new TokenString(response.access_token()),
if (response.access_token() == null) {
LOG.warn("AzureBruker tom respons {}", response);
}
var newToken = new OpenIDToken(OpenIDProvider.AZUREAD, response.token_type(), new TokenString(response.access_token()),
scopes, new TokenString(response.refresh_token()), response.expires_in());
putTokenToCache(incomingToken, scopes, newToken);
return newToken.copy();
}

private HttpRequest lagRequest(String data) {
Expand All @@ -106,4 +120,16 @@ private HttpRequest lagRequest(String data) {
.build();
}

private OpenIDToken getCachedToken(OpenIDToken incomingToken, String scopes) {
return obocache.get(cacheKey(incomingToken, scopes));
}

private void putTokenToCache(OpenIDToken incomingToken, String scopes, OpenIDToken exchangedToken) {
obocache.put(cacheKey(incomingToken, scopes), exchangedToken);
}

private String cacheKey(OpenIDToken incomingToken, String scopes) {
return scopes + ":::" + Optional.ofNullable(incomingToken.token()).orElse("");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ private AzureSystemTokenKlient() {
public synchronized OpenIDToken hentAccessToken(String scope) {
// Expiry normalt 3599 ...
var heldToken = accessToken.get(scope);
if (heldToken != null && !heldToken.isExpired()) {
if (heldToken != null && heldToken.isNotExpired()) {
return heldToken.copy();
}
var response = hentAccessToken(clientId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class StsSystemTokenKlient {
private static OpenIDToken accessToken;

public static synchronized OpenIDToken hentAccessToken() {
if (accessToken != null && !accessToken.isExpired()) {
if (accessToken != null && accessToken.isNotExpired()) {
return accessToken.copy();
}
var response = hentToken();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import no.nav.vedtak.felles.integrasjon.rest.TokenFlow;

@NativeClient
@RestClientConfig(tokenConfig = TokenFlow.CONTEXT, endpointProperty = "organisasjon.rs.url",
@RestClientConfig(tokenConfig = TokenFlow.STS_CC, endpointProperty = "organisasjon.rs.url",
endpointDefault = "https://modapp.adeo.no/ereg/api/v1/organisasjon")
@ApplicationScoped
public class OrganisasjonNativeRestKlient implements OrgInfo {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
import no.nav.vedtak.felles.integrasjon.rest.TokenFlow;

@NativeClient
@RestClientConfig(tokenConfig = TokenFlow.CONTEXT, endpointProperty = "oppgave.rs.uri",
endpointDefault = "http://oppgave.default/api/v1/oppgaver")
@RestClientConfig(tokenConfig = TokenFlow.ADAPTIVE, endpointProperty = "oppgave.rs.uri", endpointDefault = "http://oppgave.default/api/v1/oppgaver",
scopesProperty = "oppgave.scopes", scopesDefault = "api://prod-fss.oppgavehandtering.oppgave/.default")
@ApplicationScoped
public class OppgaveNativeKlient implements Oppgaver {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,10 @@ public enum FpApplication {
NONFP
;

private static final Cluster CLUSTER = Environment.current().getCluster();
private static final Namespace NAMESPACE = Environment.current().getNamespace();
private static final Environment ENV = Environment.current();
private static final Cluster CLUSTER = ENV.getCluster();
private static final Namespace NAMESPACE = ENV.getNamespace();

/*
* Utelatt fpabonnent:8065, fpinfo:8040
*/
Expand All @@ -43,6 +45,9 @@ public boolean specified() {
}

public static String contextPathFor(FpApplication application) {
if (CLUSTER.isLocal() && ENV.getProperty(application.contextPathProperty()) != null) {
return ENV.getProperty(application.contextPathProperty());
}
var prefix = "http://" + application.name().toLowerCase();
return switch (CLUSTER) {
case DEV_FSS, PROD_FSS -> prefix + "/" + application.name().toLowerCase();
Expand All @@ -55,4 +60,8 @@ public static String contextPathFor(FpApplication application) {
public static String scopesFor(FpApplication application) {
return "api://" + CLUSTER.clusterName() + "." + NAMESPACE.getName() + "." + application.name().toLowerCase() + "/.default";
}

private String contextPathProperty() {
return this.name() + ".override.url";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public static Method postJson(Object body) {
private static final Set<String> VALIDATE_HEADERS = Set.of(NavHeaders.HEADER_NAV_CALLID, NavHeaders.HEADER_NAV_CONSUMER_ID, HttpHeaders.AUTHORIZATION);

private static final String OIDC_AUTH_HEADER_PREFIX = "Bearer ";
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(15);
private static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(20);

private static final RequestContextSupplier CONTEXT_SUPPLIER = new OidcContextSupplier();

Expand Down

0 comments on commit 84d28a5

Please sign in to comment.