-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b0b47b0
commit f9ad463
Showing
16 changed files
with
371 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 0 additions & 27 deletions
27
.../main/java/no/nav/vedtak/felles/integrasjon/rest/jersey/OnBehalfOfTokenRequestFilter.java
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
57 changes: 57 additions & 0 deletions
57
...in/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXAssertionGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
import static com.nimbusds.jose.JOSEObjectType.JWT; | ||
import static com.nimbusds.jose.JWSAlgorithm.RS256; | ||
|
||
import java.time.Instant; | ||
import java.util.Date; | ||
import java.util.UUID; | ||
|
||
import com.nimbusds.jose.JOSEException; | ||
import com.nimbusds.jose.JWSHeader; | ||
import com.nimbusds.jose.crypto.RSASSASigner; | ||
import com.nimbusds.jose.jwk.RSAKey; | ||
import com.nimbusds.jwt.JWTClaimsSet; | ||
import com.nimbusds.jwt.SignedJWT; | ||
|
||
class TokenXAssertionGenerator { | ||
|
||
private final TokenXConfig cfg; | ||
private final TokenXConfigMetadata metadata; | ||
|
||
TokenXAssertionGenerator(TokenXConfig cfg, TokenXConfigMetadata metadata) { | ||
this.cfg = cfg; | ||
this.metadata = metadata; | ||
} | ||
|
||
public String assertion() { | ||
var now = Date.from(Instant.now()); | ||
try { | ||
return sign(new JWTClaimsSet.Builder() | ||
.subject(cfg.clientId()) | ||
.issuer(cfg.clientId()) | ||
.audience(metadata.tokenEndpoint().toString()) | ||
.issueTime(now) | ||
.notBeforeTime(now) | ||
.expirationTime(Date.from(Instant.now().plusSeconds(60))) | ||
.jwtID(UUID.randomUUID().toString()) | ||
.build(), cfg.rsaKey()) | ||
.serialize(); | ||
} catch (JOSEException e) { | ||
throw new IllegalArgumentException(e); | ||
} | ||
} | ||
|
||
private static SignedJWT sign(JWTClaimsSet claimsSet, RSAKey rsaKey) throws JOSEException { | ||
var signedJWT = new SignedJWT(new JWSHeader.Builder(RS256) | ||
.keyID(rsaKey.getKeyID()) | ||
.type(JWT).build(), claimsSet); | ||
signedJWT.sign(new RSASSASigner(rsaKey.toPrivateKey())); | ||
return signedJWT; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return getClass().getSimpleName() + " [cfg=" + cfg + ", metadata=" + metadata + "]"; | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
...ent/src/main/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXAudience.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
import java.util.StringJoiner; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import no.nav.foreldrepenger.konfig.Cluster; | ||
import no.nav.foreldrepenger.konfig.Namespace; | ||
|
||
public record TokenXAudience(Cluster cluster, Namespace namespace, String app) { | ||
|
||
private static final Logger LOG = LoggerFactory.getLogger(TokenXAudience.class); | ||
public String asAudience() { | ||
var joiner = new StringJoiner(":"); | ||
joiner.add(cluster.clusterName()); | ||
joiner.add(namespace.getName()); | ||
joiner.add(app); | ||
var audience = joiner.toString(); | ||
LOG.trace("Audience er {}", audience); | ||
return audience; | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
...ain/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXAudienceGenerator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
import java.net.URI; | ||
import java.util.Optional; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import lombok.val; | ||
import no.nav.foreldrepenger.konfig.Cluster; | ||
import no.nav.foreldrepenger.konfig.Environment; | ||
import no.nav.foreldrepenger.konfig.Namespace; | ||
|
||
public class TokenXAudienceGenerator { | ||
private static final Logger LOG = LoggerFactory.getLogger(TokenXAudienceGenerator.class); | ||
private static final Environment ENV = Environment.current(); | ||
|
||
public TokenXAudience audience(URI uri) { | ||
LOG.trace("Utleder audience for {}", uri); | ||
String host = uri.getHost(); | ||
val elems = host.split("\\."); | ||
|
||
if (elems.length == 1) { | ||
return new TokenXAudience(cluster(host), ENV.getNamespace(), elems[0]); | ||
} | ||
if (elems.length == 2) { | ||
return new TokenXAudience(cluster(host), Namespace.of(elems[1]), elems[0]); | ||
} | ||
throw new IllegalArgumentException("Kan ikke analysere " + host + "(" + elems.length + ")"); | ||
} | ||
|
||
private Cluster cluster(String key) { | ||
return Optional.ofNullable(ENV.getProperty(key)) | ||
.map(Cluster::of) | ||
.orElseGet(() -> ENV.getCluster()); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
...lient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
public interface TokenXClient { | ||
|
||
String exchange(String token, TokenXAudience audience); | ||
|
||
} |
32 changes: 32 additions & 0 deletions
32
...lient/src/main/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
import java.net.URI; | ||
import java.text.ParseException; | ||
|
||
import com.nimbusds.jose.jwk.RSAKey; | ||
|
||
import no.nav.foreldrepenger.konfig.Environment; | ||
|
||
public record TokenXConfig(URI wellKnownUrl, String clientId, String privateJwk) { | ||
|
||
private static final Environment ENV = Environment.current(); | ||
|
||
static TokenXConfig fraEnv() { | ||
return new TokenXConfig(ENV.getRequiredProperty("token.x.well.known.url", URI.class), | ||
ENV.getRequiredProperty("token.x.client.id"), | ||
ENV.getRequiredProperty("token.x.private.jwk")); | ||
} | ||
|
||
public RSAKey rsaKey() { | ||
try { | ||
return RSAKey.parse(privateJwk); | ||
} catch (ParseException e) { | ||
throw new IllegalArgumentException(e); | ||
} | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return getClass().getSimpleName() + " [wellKnownUrl=" + wellKnownUrl + ",clientId=" + clientId + "]"; | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
...c/main/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXConfigMetadata.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
|
||
record TokenXConfigMetadata(String issuer, | ||
@JsonProperty("token_endpoint") String tokenEndpoint, | ||
@JsonProperty("jwks_uri") String jwksUri) { | ||
} |
61 changes: 61 additions & 0 deletions
61
...src/main/java/no/nav/vedtak/felles/integrasjon/rest/jersey/tokenx/TokenXJerseyClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package no.nav.vedtak.felles.integrasjon.rest.jersey.tokenx; | ||
|
||
import static com.nimbusds.oauth2.sdk.auth.JWTAuthentication.CLIENT_ASSERTION_TYPE; | ||
import static javax.ws.rs.client.Entity.form; | ||
import static javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED_TYPE; | ||
import static javax.ws.rs.core.MediaType.APPLICATION_JSON_TYPE; | ||
|
||
import java.net.URI; | ||
|
||
import javax.ws.rs.core.Form; | ||
|
||
import no.nav.vedtak.felles.integrasjon.rest.jersey.AbstractJerseyRestClient; | ||
|
||
public class TokenXJerseyClient extends AbstractJerseyRestClient implements TokenXClient { | ||
|
||
private final TokenXAssertionGenerator assertionGenerator; | ||
private final TokenXConfigMetadata metadata; | ||
|
||
public TokenXJerseyClient() { | ||
this(TokenXConfig.fraEnv()); | ||
} | ||
|
||
public TokenXJerseyClient(TokenXConfig cfg) { | ||
this.metadata = metadataFra(cfg.wellKnownUrl()); | ||
this.assertionGenerator = new TokenXAssertionGenerator(cfg, metadata); | ||
} | ||
|
||
TokenXJerseyClient(TokenXConfigMetadata metdata, TokenXAssertionGenerator assertionGenerator) { | ||
this.metadata = metdata; | ||
this.assertionGenerator = assertionGenerator; | ||
} | ||
|
||
@Override | ||
public String exchange(String token, TokenXAudience audience) { | ||
var form = new Form() | ||
.param("subject_token", token) | ||
.param("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange") | ||
.param("client_assertion_type", CLIENT_ASSERTION_TYPE) | ||
.param("client_assertion", assertionGenerator.assertion()) | ||
.param("subject_token_type", "urn:ietf:params:oauth:token-type:jwt") | ||
.param("audience", audience.asAudience()); | ||
|
||
return client | ||
.target(metadata.tokenEndpoint()) | ||
.request(APPLICATION_FORM_URLENCODED_TYPE) | ||
.post(form(form), TokenXResponse.class).accessToken(); | ||
} | ||
|
||
private TokenXConfigMetadata metadataFra(URI uri) { | ||
return client | ||
.target(uri) | ||
.request(APPLICATION_JSON_TYPE) | ||
.get(TokenXConfigMetadata.class); | ||
|
||
} | ||
|
||
@Override | ||
public String toString() { | ||
return getClass().getSimpleName() + " [assertionGenerator=" + assertionGenerator + ", metadata=" + metadata + "]"; | ||
} | ||
} |
Oops, something went wrong.