Skip to content

Commit

Permalink
Merge branch 'master' into feature/pdl-pip-api
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsladek authored Jul 9, 2024
2 parents 29b465e + 8ca0f7c commit 8df43ec
Show file tree
Hide file tree
Showing 144 changed files with 2,977 additions and 2,606 deletions.
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ jobs:
release:
name: Feature
permissions:
contents: read
packages: write
uses: navikt/fp-gha-workflows/.github/workflows/release-feature.yml@main
with:
Expand Down
2 changes: 1 addition & 1 deletion .java-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
17
21.0
4 changes: 2 additions & 2 deletions felles/abac-kontekst/src/main/resources/META-INF/beans.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
version="3.0"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
version="4.0"
bean-discovery-mode="annotated">
</beans>
4 changes: 2 additions & 2 deletions felles/abac/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
<artifactId>felles-feil</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger</groupId>
<artifactId>konfig</artifactId>
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-konfig</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger.felles</groupId>
Expand Down
4 changes: 2 additions & 2 deletions felles/abac/src/main/resources/META-INF/beans.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
version="3.0"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
version="4.0"
bean-discovery-mode="annotated">
</beans>
4 changes: 2 additions & 2 deletions felles/abac/src/test/resources/META-INF/beans.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
version="3.0"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd"
version="4.0"
bean-discovery-mode="annotated">
</beans>
4 changes: 0 additions & 4 deletions felles/auth-filter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-oidc</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-abac</artifactId>
</dependency>
<dependency>
<groupId>jakarta.ws.rs</groupId>
<artifactId>jakarta.ws.rs-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,26 @@
import java.time.Instant;
import java.util.Optional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ResourceInfo;
import jakarta.ws.rs.core.Cookie;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import no.nav.vedtak.exception.TekniskException;
import no.nav.vedtak.log.mdc.MDCOperations;
import no.nav.vedtak.sikkerhet.abac.BeskyttetRessurs;
import no.nav.vedtak.sikkerhet.abac.ÅpenRessurs;
import no.nav.vedtak.sikkerhet.kontekst.BasisKontekst;
import no.nav.vedtak.sikkerhet.kontekst.KontekstHolder;
import no.nav.vedtak.sikkerhet.kontekst.RequestKontekst;
import no.nav.vedtak.sikkerhet.oidc.config.ConfigProvider;
import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken;
import no.nav.vedtak.sikkerhet.oidc.token.TokenString;
import no.nav.vedtak.sikkerhet.oidc.validator.JwtUtil;
import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidator;
import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorConfig;
import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorResult;

/**
* Bruksanvisning inntil alle er over og det evt samles her:
Expand Down Expand Up @@ -56,21 +52,24 @@ public static void validerSettKontekst(ResourceInfo resourceInfo, ContainerReque
public static void validerSettKontekst(ResourceInfo resourceInfo, ContainerRequestContext ctx, String cookiePath) {
try {
Method method = resourceInfo.getResourceMethod();
var beskyttetRessurs = method.getAnnotation(BeskyttetRessurs.class);
var åpenRessurs = method.getAnnotation(ÅpenRessurs.class);
var utenAutentiseringRessurs = method.getAnnotation(UtenAutentisering.class);
var metodenavn = method.getName();
LOG.trace("{} i klasse {}", metodenavn, method.getDeclaringClass());
if (KontekstHolder.harKontekst()) {
LOG.info("Kall til {} hadde kontekst {}", metodenavn, KontekstHolder.getKontekst().getKompaktUid());
KontekstHolder.fjernKontekst();
}
MDC.clear();
setCallAndConsumerId(ctx);
if (beskyttetRessurs == null && (åpenRessurs != null || method.getDeclaringClass().getName().startsWith("io.swagger"))) {
LOG.trace("{} i klasse {}", metodenavn, method.getDeclaringClass());
// Kan vurdere å unnta metodenavn = getOpenApi og getDeclaringClass startsWith io.swagger + endsWith OpenApiResource
if (utenAutentiseringRessurs != null ) {
KontekstHolder.setKontekst(BasisKontekst.ikkeAutentisertRequest(MDCOperations.getConsumerId()));
LOG.trace("{} er whitelisted", metodenavn);
} else if (beskyttetRessurs == null) {
throw new WebApplicationException(metodenavn + " mangler annotering", Response.Status.INTERNAL_SERVER_ERROR);
} else {
var tokenString = getTokenFromHeader(ctx)
.or(() -> getCookie(ctx, cookiePath))
.orElseThrow(() -> new TokenFeil("Mangler token"));
validerToken(tokenString);
var tokenString = getToken(ctx, cookiePath)
.orElseThrow(() -> new ValideringsFeil("Mangler token"));
validerTokenSetKontekst(tokenString);
setUserAndConsumerId(KontekstHolder.getKontekst().getUid());
}
} catch (TekniskException | TokenFeil e) {
throw new WebApplicationException(e, Response.Status.FORBIDDEN);
Expand All @@ -85,6 +84,7 @@ public static void fjernKontekst() {
if (KontekstHolder.harKontekst()) {
KontekstHolder.fjernKontekst();
}
MDC.clear();
}

private static void setCallAndConsumerId(ContainerRequestContext request) {
Expand All @@ -97,31 +97,33 @@ private static void setCallAndConsumerId(ContainerRequestContext request) {
.ifPresent(MDCOperations::putConsumerId);
}

private static void setUserAndConsumerId(String subject) {
Optional.ofNullable(subject).ifPresent(MDCOperations::putUserId);
if (MDCOperations.getConsumerId() == null && subject != null) {
MDCOperations.putConsumerId(subject);
}
}

private static Optional<TokenString> getToken(ContainerRequestContext request, String cookiePath) {
return getTokenFromHeader(request).or(() -> getCookieToken(request, cookiePath));
}

private static Optional<TokenString> getTokenFromHeader(ContainerRequestContext request) {
String headerValue = request.getHeaderString(AUTHORIZATION_HEADER);
return headerValue != null && headerValue.startsWith(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE)
? Optional.of(new TokenString(headerValue.substring(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE.length())))
: Optional.empty();
}

private static Optional<TokenString> getCookie(ContainerRequestContext request, String cookiePath) {
if (cookiePath == null || request.getCookies() == null) {
return Optional.empty();
}
return request.getCookies().values().stream()
.filter(c -> c.getValue() != null)
.filter(c -> ID_TOKEN_COOKIE_NAME.equalsIgnoreCase(c.getName()))
.filter(c -> cookiePath.equalsIgnoreCase(c.getPath()))
.findFirst()
.or(() -> request.getCookies().values().stream()
.filter(c -> c.getValue() != null)
.filter(c -> ID_TOKEN_COOKIE_NAME.equalsIgnoreCase(c.getName()))
.findFirst())
private static Optional<TokenString> getCookieToken(ContainerRequestContext request, String cookiePath) {
var idTokenCookie = Optional.ofNullable(request.getCookies()).map(c -> c.get(ID_TOKEN_COOKIE_NAME));
return idTokenCookie.filter(c -> cookiePath != null && cookiePath.equalsIgnoreCase(c.getPath()))
.or(() -> idTokenCookie)
.map(Cookie::getValue)
.map(TokenString::new);
}

public static void validerToken(TokenString tokenString) {
public static void validerTokenSetKontekst(TokenString tokenString) {
// Sett opp OpenIDToken
var claims = JwtUtil.getClaims(tokenString.token());
var configuration = ConfigProvider.getOpenIDConfiguration(JwtUtil.getIssuer(claims))
Expand All @@ -134,9 +136,6 @@ public static void validerToken(TokenString tokenString) {
var validateResult = tokenValidator.validate(token.primary());

// Håndter valideringsresultat
if (needToRefreshToken(token, validateResult, tokenValidator)) {
throw new ValideringsFeil("Token expired");
}
if (validateResult.isValid()) {
KontekstHolder.setKontekst(RequestKontekst.forRequest(validateResult.subject(), validateResult.compactSubject(),
validateResult.identType(), token, validateResult.getGrupper()));
Expand All @@ -146,10 +145,6 @@ public static void validerToken(TokenString tokenString) {
}
}

private static boolean needToRefreshToken(OpenIDToken token, OidcTokenValidatorResult validateResult, OidcTokenValidator tokenValidator) {
return !validateResult.isValid() && tokenValidator.validateWithoutExpirationTime(token.primary()).isValid();
}

private static class TokenFeil extends RuntimeException {
TokenFeil(String message) {
super(message);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package no.nav.vedtak.sikkerhet.jaxrs;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import jakarta.ws.rs.NameBinding;

/*
* Primært for endepunkt som kalles av plattformen (liveness, prestop, ...)
* Kan vurdere å legge til TYPE ved behov for å annotere hele interface eller klasser
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
@NameBinding
public @interface UtenAutentisering {
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,17 @@
import java.lang.reflect.Method;
import java.util.Map;

import javax.security.auth.Subject;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ResourceInfo;

import org.jose4j.json.JsonUtil;
import org.jose4j.jwt.NumericDate;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import no.nav.vedtak.sikkerhet.abac.BeskyttetRessurs;
import no.nav.vedtak.sikkerhet.abac.ÅpenRessurs;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.container.ContainerRequestContext;
import jakarta.ws.rs.container.ResourceInfo;
import no.nav.vedtak.sikkerhet.kontekst.IdentType;
import no.nav.vedtak.sikkerhet.kontekst.KontekstHolder;
import no.nav.vedtak.sikkerhet.kontekst.SikkerhetContext;
Expand All @@ -36,14 +32,11 @@

class AuthenticationFilterDelegateTest {

private OidcTokenValidator tokenValidator = Mockito.mock(OidcTokenValidator.class);
private final OidcTokenValidator tokenValidator = Mockito.mock(OidcTokenValidator.class);

private ContainerRequestContext request = Mockito.mock(ContainerRequestContext.class);
private final ContainerRequestContext request = Mockito.mock(ContainerRequestContext.class);

private Subject subject = new Subject();
private Subject serviceSubject = new Subject();

public void setupAll() throws Exception {
public void setupAll() {

System.setProperty(AzureProperty.AZURE_APP_WELL_KNOWN_URL.name(),
OidcTokenGenerator.ISSUER + "/" + WellKnownConfigurationHelper.STANDARD_WELL_KNOWN_PATH);
Expand All @@ -60,13 +53,13 @@ public void setupAll() throws Exception {
}

@BeforeEach
public void setUp() throws Exception {
public void setUp() {
WellKnownConfigurationHelper.unsetWellKnownConfig();
setupAll();
}

@AfterEach
public void teardown() throws Exception {
public void teardown() {
System.clearProperty(AzureProperty.AZURE_APP_WELL_KNOWN_URL.name());
System.clearProperty(AzureProperty.AZURE_APP_CLIENT_ID.name());
System.clearProperty(AzureProperty.AZURE_OPENID_CONFIG_ISSUER.name());
Expand Down Expand Up @@ -94,6 +87,11 @@ public void teardown() throws Exception {
when(request.getHeaderString("Authorization")).thenReturn(null);

assertThrows(WebApplicationException.class, () -> AuthenticationFilterDelegate.validerSettKontekst(ri, request));
try {
AuthenticationFilterDelegate.validerSettKontekst(ri, request);
} catch (WebApplicationException e) {
assertThat(e.getResponse().getStatus()).isEqualTo(401);
}
}


Expand All @@ -103,11 +101,16 @@ public void teardown() throws Exception {
Method method = RestClass.class.getMethod("beskyttet");
ResourceInfo ri = new TestInvocationContext(method, RestClass.class);

when(request.getHeaderString("Authorization")).thenReturn(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE + utløptIdToken);
when(request.getHeaderString("Authorization")).thenReturn(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE + utløptIdToken.token());

when(tokenValidator.validate(utløptIdToken)).thenReturn(OidcTokenValidatorResult.invalid("expired"));

assertThrows(WebApplicationException.class, () -> AuthenticationFilterDelegate.validerSettKontekst(ri, request));
try {
AuthenticationFilterDelegate.validerSettKontekst(ri, request);
} catch (WebApplicationException e) {
assertThat(e.getResponse().getStatus()).isEqualTo(401);
}

}

Expand Down Expand Up @@ -175,22 +178,21 @@ private static TokenString getGyldigToken() {
@Path("foo")
static class RestClass {

@ÅpenRessurs
@UtenAutentisering
@Path("ubeskyttet")
public void ubeskyttet() {
}

@BeskyttetRessurs()
@Path("beskyttet")
public void beskyttet() {
}

}

private class TestInvocationContext implements ResourceInfo {
private static class TestInvocationContext implements ResourceInfo {

private Method method;
private Class<?> resourceClass;
private final Method method;
private final Class<?> resourceClass;

TestInvocationContext(Method method, Class<?> resourceClass) {
this.method = method;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@
import java.util.List;
import java.util.Properties;

import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.bytecode.spi.ClassTransformer;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;

import jakarta.persistence.SharedCacheMode;
import jakarta.persistence.ValidationMode;
import jakarta.persistence.spi.PersistenceUnitTransactionType;

import org.hibernate.bytecode.enhance.spi.EnhancementContext;
import org.hibernate.jpa.boot.spi.PersistenceUnitDescriptor;

/**
* Delegerer kall fra en {@link PersistenceUnitDescriptor} til en annen slik at det er enklere å lage en SPI implementasjon baser på Hibernate
*/
public class DelegatingPersistenceUnitDescriptor implements PersistenceUnitDescriptor {
private PersistenceUnitDescriptor persistenceUnitDescriptor;
private final PersistenceUnitDescriptor persistenceUnitDescriptor;

public DelegatingPersistenceUnitDescriptor(PersistenceUnitDescriptor persistenceUnitDescriptor) {
this.persistenceUnitDescriptor = persistenceUnitDescriptor;
Expand Down Expand Up @@ -106,4 +107,9 @@ public void pushClassTransformer(EnhancementContext enhancementContext) {
persistenceUnitDescriptor.pushClassTransformer(enhancementContext);
}

@Override
public ClassTransformer getClassTransformer() {
return persistenceUnitDescriptor.getClassTransformer();
}

}
Loading

0 comments on commit 8df43ec

Please sign in to comment.