From 98b5c40348938240410e17f965fcbd0e1220efec Mon Sep 17 00:00:00 2001 From: Jens-Otto Larsen <46576810+jolarsen@users.noreply.github.com> Date: Fri, 24 Feb 2023 08:31:03 +0100 Subject: [PATCH] Fjerne abac-legacy og containerlogin, Legg til JaxRs-auth-filter (#1252) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fjerne abac-legacy og containerlogin, Legg til JaxRs-auth-filter * Søtte azure-pip --- .../sikkerhet/abac/LegacyTokenProvider.java | 32 --- felles/abac/README.md | 4 +- .../no/nav/vedtak/sikkerhet/abac/PepImpl.java | 6 +- .../sikkerhet/abac/\303\205penRessurs.java" | 18 ++ felles/{abac-legacy => auth-filter}/pom.xml | 27 ++- .../jaxrs/AuthenticationFilterDelegate.java | 164 +++++++++++++ .../src/main/resources/META-INF/beans.xml | 0 .../AuthenticationFilterDelegateTest.java | 217 ++++++++++++++++++ .../vedtak/sikkerhet/jaxrs/KeyStoreTool.java | 94 ++++++++ .../sikkerhet/jaxrs/OidcTokenGenerator.java | 75 ++++++ .../src/test/resources/test-keystore.jks | Bin 0 -> 2553 bytes ...k.sikkerhet.loginmodule.LoginConfiguration | 1 - felles/pom.xml | 6 +- .../java/no/nav/vedtak/sikkerhet/README.md | 3 +- .../sikkerhet/context/ContextCleaner.java | 41 ++++ .../sikkerhet/loginmodule/ContainerLogin.java | 119 ---------- .../sikkerhet/jaspic/OidcAuthModuleTest.java | 3 +- .../OidcTokenValidatorProviderForTest.java | 13 -- 18 files changed, 643 insertions(+), 180 deletions(-) delete mode 100644 felles/abac-legacy/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/LegacyTokenProvider.java create mode 100644 "felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/\303\205penRessurs.java" rename felles/{abac-legacy => auth-filter}/pom.xml (50%) create mode 100644 felles/auth-filter/src/main/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegate.java rename felles/{abac-legacy => auth-filter}/src/main/resources/META-INF/beans.xml (100%) create mode 100644 felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegateTest.java create mode 100644 felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/KeyStoreTool.java create mode 100644 felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/OidcTokenGenerator.java create mode 100644 felles/auth-filter/src/test/resources/test-keystore.jks delete mode 100644 felles/oidc/src/main/resources/META-INF/services/no.nav.vedtak.sikkerhet.loginmodule.LoginConfiguration create mode 100644 felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/context/ContextCleaner.java delete mode 100644 felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/loginmodule/ContainerLogin.java delete mode 100644 felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcTokenValidatorProviderForTest.java diff --git a/felles/abac-legacy/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/LegacyTokenProvider.java b/felles/abac-legacy/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/LegacyTokenProvider.java deleted file mode 100644 index ea03db860..000000000 --- a/felles/abac-legacy/src/main/java/no/nav/foreldrepenger/sikkerhet/abac/LegacyTokenProvider.java +++ /dev/null @@ -1,32 +0,0 @@ -package no.nav.foreldrepenger.sikkerhet.abac; - -import javax.enterprise.context.Dependent; - -import no.nav.vedtak.sikkerhet.abac.TokenProvider; -import no.nav.vedtak.sikkerhet.context.SubjectHandler; -import no.nav.vedtak.sikkerhet.kontekst.IdentType; -import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; - -@Dependent -public class LegacyTokenProvider implements TokenProvider { - - @Override - public String getUid() { - return SubjectHandler.getSubjectHandler().getUid(); - } - - @Override - public IdentType getIdentType() { - return SubjectHandler.getSubjectHandler().getIdentType(); - } - - @Override - public OpenIDToken openIdToken() { - return SubjectHandler.getSubjectHandler().getOpenIDToken(); - } - - @Override - public String samlToken() { - return SubjectHandler.getSubjectHandler().getSamlToken().getTokenAsString(); - } -} diff --git a/felles/abac/README.md b/felles/abac/README.md index 6788842ef..a2904df64 100644 --- a/felles/abac/README.md +++ b/felles/abac/README.md @@ -26,7 +26,7 @@ Det vil mangle en implementasjon av TokenProvider og det er mulig å implementer ``` no.nav.foreldrepenger.felles - felles-abac-legacy + felles-abac-kontekst ``` -Denne kommer med en avhengighet til felles-sikkerhet og SubjectHandler. +Denne kommer med en avhengighet til felles-kontekst og KontekstHolder. diff --git a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java index 506851bf5..2a3873155 100644 --- a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java +++ b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/PepImpl.java @@ -61,7 +61,7 @@ public Tilgangsbeslutning vurderTilgang(BeskyttetRessursAttributter beskyttetRes if (PIP.equals(beskyttetRessursAttributter.getResourceType())) { return vurderTilgangTilPipTjeneste(beskyttetRessursAttributter, appRessurser); } - if (skalForetaLokalTilgangsbeslutning(beskyttetRessursAttributter)) { + if (kanForetaLokalTilgangsbeslutning(beskyttetRessursAttributter)) { return new Tilgangsbeslutning(harTilgang(beskyttetRessursAttributter) ? GODKJENT : AVSLÅTT_ANNEN_ÅRSAK, beskyttetRessursAttributter, appRessurser); } return pdpKlient.forespørTilgang(beskyttetRessursAttributter, builder.abacDomene(), appRessurser); @@ -70,7 +70,7 @@ public Tilgangsbeslutning vurderTilgang(BeskyttetRessursAttributter beskyttetRes // AzureAD CC kommer med sub som ikke ikke en bruker med vanlige AD-grupper og roller // Token kan utvides med roles og groups - men oppsettet er langt fra det som er kjent fra STS mv. // Kan legge inn filter på claims/roles intern og/eller ekstern. - private boolean skalForetaLokalTilgangsbeslutning(BeskyttetRessursAttributter attributter) { + private boolean kanForetaLokalTilgangsbeslutning(BeskyttetRessursAttributter attributter) { var identType = attributter.getToken().getIdentType(); var consumer = attributter.getToken().getBrukerId(); return OpenIDProvider.AZUREAD.equals(attributter.getToken().getOpenIDProvider()) @@ -92,6 +92,8 @@ protected Tilgangsbeslutning vurderTilgangTilPipTjeneste(BeskyttetRessursAttribu String uid = tokenProvider.getUid(); if (pipUsers.contains(uid.toLowerCase())) { return new Tilgangsbeslutning(GODKJENT, beskyttetRessursAttributter, appRessursData); + } else if (kanForetaLokalTilgangsbeslutning(beskyttetRessursAttributter) && harTilgang(beskyttetRessursAttributter)) { + return new Tilgangsbeslutning(GODKJENT, beskyttetRessursAttributter, appRessursData); } else { return new Tilgangsbeslutning(AVSLÅTT_ANNEN_ÅRSAK, beskyttetRessursAttributter, appRessursData); } diff --git "a/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/\303\205penRessurs.java" "b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/\303\205penRessurs.java" new file mode 100644 index 000000000..65fd9d101 --- /dev/null +++ "b/felles/abac/src/main/java/no/nav/vedtak/sikkerhet/abac/\303\205penRessurs.java" @@ -0,0 +1,18 @@ +package no.nav.vedtak.sikkerhet.abac; + +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 javax.interceptor.InterceptorBinding; +import javax.ws.rs.NameBinding; + +@Inherited +@InterceptorBinding +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE, ElementType.METHOD }) +@NameBinding +public @interface ÅpenRessurs { +} diff --git a/felles/abac-legacy/pom.xml b/felles/auth-filter/pom.xml similarity index 50% rename from felles/abac-legacy/pom.xml rename to felles/auth-filter/pom.xml index 4827ca18b..cb9b9b3c8 100644 --- a/felles/abac-legacy/pom.xml +++ b/felles/auth-filter/pom.xml @@ -2,24 +2,41 @@ + 4.0.0 + felles no.nav.foreldrepenger.felles 0.0.0-SNAPSHOT - 4.0.0 - felles-abac-legacy - Felles :: ABAC + + felles-auth-filter + Felles :: Auth-filter + jar - no.nav.foreldrepenger.felles.sikkerhet - felles-sikkerhet + no.nav.foreldrepenger.felles + felles-log + + + no.nav.foreldrepenger.felles + felles-oidc no.nav.foreldrepenger.felles felles-abac + + jakarta.ws.rs + jakarta.ws.rs-api + + + org.glassfish.jersey.core + jersey-server + test + + diff --git a/felles/auth-filter/src/main/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegate.java b/felles/auth-filter/src/main/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegate.java new file mode 100644 index 000000000..7fb10813f --- /dev/null +++ b/felles/auth-filter/src/main/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegate.java @@ -0,0 +1,164 @@ +package no.nav.vedtak.sikkerhet.jaxrs; + +import java.lang.reflect.Method; +import java.time.Instant; +import java.util.Optional; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Cookie; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response; + +import org.jose4j.jwt.MalformedClaimException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +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: + * - App må lage et filter som implementerer ContainerRequestFilter + * - Filter må annotert med Provider og legges inn i Application/getClasses() + * - Legg på @Context private ResourceInfo resourceinfo + * - Kall AuthenticationFilterDelegate . validerSettKontekst og la evt exceptions passere ut til Jersey + * + * App må også ha et ContainerResponseFilter som kaller AuthenticationFilterDelegate . fjernKontekst + */ +public class AuthenticationFilterDelegate { + + private static final Logger LOG = LoggerFactory.getLogger(AuthenticationFilterDelegate.class); + + private static final String ID_TOKEN_COOKIE_NAME = "ID_token"; + private static final String AUTHORIZATION_HEADER = HttpHeaders.AUTHORIZATION; + + private AuthenticationFilterDelegate() { + } + + + public static void validerSettKontekst(ResourceInfo resourceInfo, ContainerRequestContext ctx) { + validerSettKontekst(resourceInfo, ctx, null); + } + + 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 metodenavn = method.getName(); + LOG.trace("{} i klasse {}", metodenavn, method.getDeclaringClass()); + setCallAndConsumerId(ctx); + if (beskyttetRessurs == null && (åpenRessurs != null || method.getDeclaringClass().getName().startsWith("io.swagger"))) { + 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); + } + } catch (MalformedClaimException|TokenFeil e) { + throw new WebApplicationException(e, Response.Status.FORBIDDEN); + } catch (WebApplicationException e) { + throw e; + } catch (Exception e) { + throw new WebApplicationException(e, Response.Status.UNAUTHORIZED); + } + } + + public static void fjernKontekst() { + if (KontekstHolder.harKontekst()) { + KontekstHolder.fjernKontekst(); + } + } + + private static void setCallAndConsumerId(ContainerRequestContext request) { + String callId = Optional.ofNullable(request.getHeaderString(MDCOperations.HTTP_HEADER_CALL_ID)) // NOSONAR Akseptertet headere + .or(() -> Optional.ofNullable(request.getHeaderString(MDCOperations.HTTP_HEADER_ALT_CALL_ID))) + .orElseGet(MDCOperations::generateCallId); + MDCOperations.putCallId(callId); + + Optional.ofNullable(request.getHeaderString(MDCOperations.HTTP_HEADER_CONSUMER_ID)) + .ifPresent(MDCOperations::putConsumerId); + } + + private static Optional 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 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()) + .map(Cookie::getValue) + .map(TokenString::new); + } + + public static void validerToken(TokenString tokenString) throws MalformedClaimException { + // Sett opp OpenIDToken + var claims = JwtUtil.getClaims(tokenString.token()); + var configuration = ConfigProvider.getOpenIDConfiguration(claims.getIssuer()) + .orElseThrow(() -> new TokenFeil("Token mangler issuer claim")); + var expiresAt = Optional.ofNullable(JwtUtil.getExpirationTime(claims)).orElseGet(() -> Instant.now().plusSeconds(300)); + var token = new OpenIDToken(configuration.type(), OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE, tokenString, null, expiresAt.toEpochMilli()); + + // Valider + var tokenValidator = OidcTokenValidatorConfig.instance().getValidator(token.provider()); + 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)); + LOG.trace("token validert"); + } else { + throw new ValideringsFeil("Ugyldig token"); + } + } + + 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); + } + } + + private static class ValideringsFeil extends RuntimeException { + ValideringsFeil(String message) { + super(message); + } + } + +} diff --git a/felles/abac-legacy/src/main/resources/META-INF/beans.xml b/felles/auth-filter/src/main/resources/META-INF/beans.xml similarity index 100% rename from felles/abac-legacy/src/main/resources/META-INF/beans.xml rename to felles/auth-filter/src/main/resources/META-INF/beans.xml diff --git a/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegateTest.java b/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegateTest.java new file mode 100644 index 000000000..53a64abde --- /dev/null +++ b/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/AuthenticationFilterDelegateTest.java @@ -0,0 +1,217 @@ +package no.nav.vedtak.sikkerhet.jaxrs; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.when; + +import java.lang.reflect.Method; +import java.util.Map; + +import javax.security.auth.Subject; +import javax.ws.rs.Path; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.container.ContainerRequestContext; +import javax.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 no.nav.vedtak.sikkerhet.kontekst.IdentType; +import no.nav.vedtak.sikkerhet.kontekst.KontekstHolder; +import no.nav.vedtak.sikkerhet.kontekst.SikkerhetContext; +import no.nav.vedtak.sikkerhet.oidc.config.AzureProperty; +import no.nav.vedtak.sikkerhet.oidc.config.OpenIDProvider; +import no.nav.vedtak.sikkerhet.oidc.config.impl.WellKnownConfigurationHelper; +import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; +import no.nav.vedtak.sikkerhet.oidc.token.TokenString; +import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidator; +import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorConfig; +import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorResult; + +public class AuthenticationFilterDelegateTest { + + private OidcTokenValidator tokenValidator = Mockito.mock(OidcTokenValidator.class); + + private ContainerRequestContext request = Mockito.mock(ContainerRequestContext.class); + + private Subject subject = new Subject(); + private Subject serviceSubject = new Subject(); + + public void setupAll() throws Exception { + + System.setProperty(AzureProperty.AZURE_APP_WELL_KNOWN_URL.name(), OidcTokenGenerator.ISSUER + "/" + WellKnownConfigurationHelper.STANDARD_WELL_KNOWN_PATH); + System.setProperty(AzureProperty.AZURE_APP_CLIENT_ID.name(), "OIDC"); + System.setProperty(AzureProperty.AZURE_OPENID_CONFIG_ISSUER.name(), OidcTokenGenerator.ISSUER); + System.setProperty(AzureProperty.AZURE_OPENID_CONFIG_JWKS_URI.name(), OidcTokenGenerator.ISSUER + "/jwks_uri"); + System.setProperty("systembruker.username", "JUnit Test"); + + Map testData = Map.of( + "issuer", OidcTokenGenerator.ISSUER, + AzureProperty.AZURE_OPENID_CONFIG_JWKS_URI.name(), OidcTokenGenerator.ISSUER + "/jwks_uri" + ); + WellKnownConfigurationHelper.setWellKnownConfig(OidcTokenGenerator.ISSUER + "/" + WellKnownConfigurationHelper.STANDARD_WELL_KNOWN_PATH, JsonUtil.toJson(testData)); + OidcTokenValidatorConfig.addValidator(OpenIDProvider.AZUREAD, tokenValidator); + } + + @BeforeEach + public void setUp() throws Exception{ + WellKnownConfigurationHelper.unsetWellKnownConfig(); + setupAll(); + } + + @AfterEach + public void teardown() throws Exception{ + 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()); + System.clearProperty(AzureProperty.AZURE_OPENID_CONFIG_JWKS_URI.name()); + System.clearProperty("systembruker.username"); + + } + + @Test + public void skal_slippe_gjennom_forespørsel_etter_ubeskyttet_ressurs() throws Exception { + Method method = RestClass.class.getMethod("ubeskyttet"); + ResourceInfo ri = new TestInvocationContext(method, RestClass.class); + + AuthenticationFilterDelegate.validerSettKontekst(ri, request); + assertThat(KontekstHolder.getKontekst().getContext()).isEqualTo(SikkerhetContext.REQUEST); + assertThat(KontekstHolder.getKontekst().getUid()).isNull(); + } + + + @Test + public void skal_ikke_slippe_gjennom_forespørsel_men_svare_med_401_etter_beskyttet_ressurs_når_forespørselen_ikke_har_med_id_token() throws Exception { + Method method = RestClass.class.getMethod("beskyttet"); + ResourceInfo ri = new TestInvocationContext(method, RestClass.class); + + when(request.getHeaderString("Authorization")).thenReturn(null); + + assertThrows(WebApplicationException.class, () -> AuthenticationFilterDelegate.validerSettKontekst(ri, request)); + } + + + @Test + public void skal_sende_401_for_utløpt_Authorization_header() throws Exception { + var utløptIdToken = getUtløptToken(); + 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(tokenValidator.validate(utløptIdToken)) + .thenReturn(OidcTokenValidatorResult.invalid("expired")); + + assertThrows(WebApplicationException.class, () -> AuthenticationFilterDelegate.validerSettKontekst(ri, request)); + + } + + @Test + public void skal_slippe_gjennom_forespørsel_etter_beskyttet_ressurs_når_forespørselen_har_med_id_token_som_validerer() + throws Exception { + Method method = RestClass.class.getMethod("beskyttet"); + ResourceInfo ri = new TestInvocationContext(method, RestClass.class); + + var gyldigToken = getGyldigToken(); + + when(request.getHeaderString("Authorization")).thenReturn(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE + gyldigToken.token()); + + when(tokenValidator.validate(gyldigToken)) + .thenReturn(OidcTokenValidatorResult.valid("demo", IdentType.utledIdentType("demo"), System.currentTimeMillis() / 1000 + 121)); + + AuthenticationFilterDelegate.validerSettKontekst(ri, request); + assertThat(KontekstHolder.getKontekst().getContext()).isEqualTo(SikkerhetContext.REQUEST); + assertThat(KontekstHolder.getKontekst().getUid()).isNotNull(); + } + + + + @Test + public void skal_slippe_gjennom_token_tilstrekkelig_levetid_til_å_brukes_til_kall_til_andre_tjenester() + throws Exception { + Method method = RestClass.class.getMethod("beskyttet"); + ResourceInfo ri = new TestInvocationContext(method, RestClass.class); + + int sekunderGjenståendeGyldigTid = 125; + + var gyldigToken = getGyldigToken(); + when(request.getHeaderString("Authorization")).thenReturn(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE + gyldigToken.token()); + when(tokenValidator.validate(gyldigToken)) + .thenReturn(OidcTokenValidatorResult.valid("demo", IdentType.utledIdentType("demo"), System.currentTimeMillis() / 1000 + sekunderGjenståendeGyldigTid)); + + AuthenticationFilterDelegate.validerSettKontekst(ri, request); + assertThat(KontekstHolder.getKontekst().getContext()).isEqualTo(SikkerhetContext.REQUEST); + assertThat(KontekstHolder.getKontekst().getUid()).isNotNull(); + } + + @Test + public void skal_slippe_gjennom_token_tilstrekkelig_levetid_til_å_brukes_til_kall_til_andre_tjenester_selv_om_kortere_enn_gammel_grense() + throws Exception { + Method method = RestClass.class.getMethod("beskyttet"); + ResourceInfo ri = new TestInvocationContext(method, RestClass.class); + + int sekunderGjenståendeGyldigTid = 115; + + var gyldigToken = getGyldigToken(); + when(request.getHeaderString("Authorization")).thenReturn(OpenIDToken.OIDC_DEFAULT_TOKEN_TYPE + gyldigToken.token()); + when(tokenValidator.validate(gyldigToken)) + .thenReturn(OidcTokenValidatorResult.valid("demo", IdentType.utledIdentType("demo"), System.currentTimeMillis() / 1000 + sekunderGjenståendeGyldigTid)); + + AuthenticationFilterDelegate.validerSettKontekst(ri, request); + assertThat(KontekstHolder.getKontekst().getContext()).isEqualTo(SikkerhetContext.REQUEST); + assertThat(KontekstHolder.getKontekst().getUid()).isNotNull(); + } + + + private static TokenString getGyldigToken() { + return new OidcTokenGenerator().createCookieTokenHolder(); + } + + private static TokenString getUtløptToken() { + return new OidcTokenGenerator().withExpiration(NumericDate.fromMilliseconds(System.currentTimeMillis() - 1)).createCookieTokenHolder(); + } + + @Path("foo") + static class RestClass { + + @ÅpenRessurs + @Path("ubeskyttet") + public void ubeskyttet() { + } + + @BeskyttetRessurs() + @Path("beskyttet") + public void beskyttet() { + } + + } + + private class TestInvocationContext implements ResourceInfo { + + private Method method; + private Class resourceClass; + + TestInvocationContext(Method method, Class resourceClass) { + this.method = method; + this.resourceClass = resourceClass; + } + + @Override + public Method getResourceMethod() { + return method; + } + + @Override + public Class getResourceClass() { + return resourceClass; + } + + } + +} diff --git a/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/KeyStoreTool.java b/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/KeyStoreTool.java new file mode 100644 index 000000000..edf9345a1 --- /dev/null +++ b/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/KeyStoreTool.java @@ -0,0 +1,94 @@ +package no.nav.vedtak.sikkerhet.jaxrs; + +import java.io.IOException; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.UnrecoverableEntryException; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.interfaces.RSAPublicKey; + +import org.jose4j.base64url.Base64Url; +import org.jose4j.jwk.PublicJsonWebKey; +import org.jose4j.jwk.RsaJsonWebKey; +import org.jose4j.lang.JoseException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class KeyStoreTool { + + private static RsaJsonWebKey jwk = null; + + private static final Logger LOG = LoggerFactory.getLogger(KeyStoreTool.class); + + static { + + PublicKey myPublicKey; + PrivateKey myPrivateKey; + char[] keystorePassword = getKeyStoreAndKeyPassword(); + String keyAndCertAlias = getKeyAndCertAlias(); + + try (InputStream keystoreFile = KeyStoreTool.class.getResourceAsStream("/test-keystore.jks")) { + KeyStore ks = KeyStore.getInstance("JKS"); + ks.load(keystoreFile, keystorePassword); + + KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(keystorePassword); + KeyStore.PrivateKeyEntry pk = (KeyStore.PrivateKeyEntry) ks.getEntry(keyAndCertAlias, protParam); + myPrivateKey = pk.getPrivateKey(); + Certificate cert = ks.getCertificate(keyAndCertAlias); + myPublicKey = cert.getPublicKey(); + + //KeyStoreTool.keystore = ks; + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | UnrecoverableEntryException e) { + LOG.error("Error during loading of keystore. Do you have your keystore in order, soldier?", e); + throw new RuntimeException(e); + } + + try { + jwk = (RsaJsonWebKey) PublicJsonWebKey.Factory.newPublicJwk(myPublicKey); + jwk.setPrivateKey(myPrivateKey); + jwk.setKeyId("1"); + } catch (JoseException e) { + LOG.error("Error during init of JWK: " + e); + throw new RuntimeException(e); + } + + } + + public static char[] getKeyStoreAndKeyPassword() { + return "changeit".toCharArray(); + } + + public static String getKeyAndCertAlias() { + return System.getProperty("no.nav.modig.security.appkey", "app-key"); + } + + public static RsaJsonWebKey getJsonWebKey() { + return jwk; + } + + public static String getJwks() { + String kty = "RSA"; + String kid = "1"; + String use = "sig"; + String alg = "RS256"; + String e = Base64Url.encode(jwk.getRsaPublicKey().getPublicExponent().toByteArray()); + RSAPublicKey publicKey = (RSAPublicKey) jwk.getPublicKey(); + + byte[] bytes = publicKey.getModulus().toByteArray(); + String n = Base64Url.encode(bytes); + + return String.format("{\"keys\":[{" + + "\"kty\":\"%s\"," + + "\"alg\":\"%s\"," + + "\"use\":\"%s\"," + + "\"kid\":\"%s\"," + + "\"n\":\"%s\"," + + "\"e\":\"%s\"" + + "}]}", kty, alg, use, kid, n, e); + } +} diff --git a/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/OidcTokenGenerator.java b/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/OidcTokenGenerator.java new file mode 100644 index 000000000..b9a62d6b0 --- /dev/null +++ b/felles/auth-filter/src/test/java/no/nav/vedtak/sikkerhet/jaxrs/OidcTokenGenerator.java @@ -0,0 +1,75 @@ +package no.nav.vedtak.sikkerhet.jaxrs; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.jose4j.jwk.RsaJsonWebKey; +import org.jose4j.jws.AlgorithmIdentifiers; +import org.jose4j.jws.JsonWebSignature; +import org.jose4j.jwt.JwtClaims; +import org.jose4j.jwt.NumericDate; +import org.jose4j.lang.JoseException; + +import no.nav.vedtak.sikkerhet.oidc.token.TokenString; + +public class OidcTokenGenerator { + public static final String ISSUER = "https://foo.bar.adeo.no/azure/oauth2"; + private List aud = Collections.singletonList("OIDC"); + private NumericDate expiration = NumericDate.fromSeconds(NumericDate.now().getValue() + 3600); + private String issuer = ISSUER; + private NumericDate issuedAt = NumericDate.now(); + private String subject = "demo"; + private String kid; + + private Map additionalClaims = new HashMap<>(); + + public OidcTokenGenerator() { + additionalClaims.put("azp", "OIDC"); + } + + public OidcTokenGenerator withExpiration(NumericDate expiration) { + this.expiration = expiration; + return this; + } + + + public TokenString createCookieTokenHolder() { + return new TokenString(create()); + } + + public String create() { + if (kid == null) { + kid = KeyStoreTool.getJsonWebKey().getKeyId(); + } + + JwtClaims claims = new JwtClaims(); + claims.setIssuer(issuer); + claims.setExpirationTime(expiration); + claims.setGeneratedJwtId(); + claims.setIssuedAt(issuedAt); + claims.setSubject(subject); + if (aud.size() == 1) { + claims.setAudience(aud.get(0)); + } else { + claims.setAudience(aud); + } + for (Map.Entry entry : additionalClaims.entrySet()) { + claims.setStringClaim(entry.getKey(), entry.getValue()); + } + RsaJsonWebKey senderJwk = KeyStoreTool.getJsonWebKey(); + JsonWebSignature jws = new JsonWebSignature(); + jws.setPayload(claims.toJson()); + jws.setKeyIdHeaderValue(kid); + jws.setAlgorithmHeaderValue("RS256"); + jws.setKey(senderJwk.getPrivateKey()); + jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256); + + try { + return jws.getCompactSerialization(); + } catch (JoseException e) { + throw new RuntimeException(e); + } + } +} diff --git a/felles/auth-filter/src/test/resources/test-keystore.jks b/felles/auth-filter/src/test/resources/test-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..de0cca21a5213aca64ef3fdb89ce7d9589c66e64 GIT binary patch literal 2553 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 literal 0 HcmV?d00001 diff --git a/felles/oidc/src/main/resources/META-INF/services/no.nav.vedtak.sikkerhet.loginmodule.LoginConfiguration b/felles/oidc/src/main/resources/META-INF/services/no.nav.vedtak.sikkerhet.loginmodule.LoginConfiguration deleted file mode 100644 index b658b06e5..000000000 --- a/felles/oidc/src/main/resources/META-INF/services/no.nav.vedtak.sikkerhet.loginmodule.LoginConfiguration +++ /dev/null @@ -1 +0,0 @@ -no.nav.vedtak.sikkerhet.loginmodule.oidc.OIDCLoginConfiguration diff --git a/felles/pom.xml b/felles/pom.xml index b1d8b7227..6b03a50ce 100644 --- a/felles/pom.xml +++ b/felles/pom.xml @@ -24,9 +24,9 @@ db abac xmlutils - abac-legacy kontekst abac-kontekst + auth-filter @@ -58,12 +58,12 @@ no.nav.foreldrepenger.felles - felles-abac-legacy + felles-abac-kontekst ${project.version} no.nav.foreldrepenger.felles - felles-abac-kontekst + felles-auth-filter ${project.version} diff --git a/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/README.md b/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/README.md index 1272f5694..d9d624e44 100644 --- a/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/README.md +++ b/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/README.md @@ -3,7 +3,7 @@ Denne modulen dekker JASPI, JAAS og Tokenvalidering Kode relatert til Context, OIDC-config og Tokenhenting/veksling ligger i felles-oidc -Sikkerhetskontekst aksesseres via SubjectHandler og henter informasjon enten fra request sin **Authentication** eller det som er satt opp i tråden +Sikkerhetskontekst skal hentes fra KontekstHolder, ikke via SubjectHandler Kort om hovedkomponentene @@ -21,7 +21,6 @@ LoginModule(s) * Får inn subject og callback i initialize() * Vanlig OIDC-requests håndteres ved tokenvalidering og setter Authentication for request * SAML-requests håndteres ved tokenvalidering og setter en trådlokal kontekst -* Prosesstask/Containerlogin henter et systemtoken som valideres og setter trådlokal kontekst OidcTokenValidator validerer tokens fra ulike issuers og henter jwks til keycache. Er for tiden en blanding av jose4j og nimbusds (og litt no nav sikkerhet) diff --git a/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/context/ContextCleaner.java b/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/context/ContextCleaner.java new file mode 100644 index 000000000..35731d8a4 --- /dev/null +++ b/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/context/ContextCleaner.java @@ -0,0 +1,41 @@ +package no.nav.vedtak.sikkerhet.context; + +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import no.nav.vedtak.sikkerhet.kontekst.KontekstHolder; + +public class ContextCleaner { + + private static final Logger LOG = LoggerFactory.getLogger(ContextCleaner.class); + + private ContextCleaner() { + } + + public static void enusureCleanContext() { + try { + if (KontekstHolder.harKontekst()) { + LOG.trace("FPFELLES KONTEKST fjernet i ContextCleaner - burde vært fjernet før"); + KontekstHolder.fjernKontekst(); + } + var subjectHandler = SubjectHandler.getSubjectHandler(); + var subject = subjectHandler.getSubject(); + // OBS viss fare for at JettySubjectHandler kan gi ting fra request så lenge den ikke er ferdig destroyed + if (subject != null ) { + final Set credidentialClasses = subject.getPublicCredentials().stream() + .map(pc -> pc.getClass().getName()) + .collect(Collectors.toSet()); + if (!credidentialClasses.isEmpty() || !subject.getPrincipals().isEmpty()) { + LOG.info("FPFELLES ConClean: inneholdt principals {} og PublicCredentials klasser {}",subject.getPrincipals(), credidentialClasses); + } + ((ThreadLocalSubjectHandler) subjectHandler).setSubject(null); + LOG.trace("FPFELLES ConClean: subject fjernet fra ThreadLocal"); + } + } catch (Exception e) { + LOG.trace("FPFELLES ConClean: kunne ikke fjerne subject", e); + } + } +} diff --git a/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/loginmodule/ContainerLogin.java b/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/loginmodule/ContainerLogin.java deleted file mode 100644 index 5a8c4e060..000000000 --- a/felles/sikkerhet/src/main/java/no/nav/vedtak/sikkerhet/loginmodule/ContainerLogin.java +++ /dev/null @@ -1,119 +0,0 @@ -package no.nav.vedtak.sikkerhet.loginmodule; - -import java.util.Map; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.AppConfigurationEntry; -import javax.security.auth.login.Configuration; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; - -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.TokenCallback; -import no.nav.vedtak.sikkerhet.context.SubjectHandler; -import no.nav.vedtak.sikkerhet.kontekst.IdentType; -import no.nav.vedtak.sikkerhet.kontekst.KontekstHolder; -import no.nav.vedtak.sikkerhet.kontekst.RequestKontekst; -import no.nav.vedtak.sikkerhet.kontekst.Systembruker; -import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; -import no.nav.vedtak.sikkerhet.oidc.token.TokenProvider; - -/** - * Programmatisk innlogging på en tråd i containeren. Brukes av bakgrunnsjobber - * (eks. prosesstask) slik at disse er autentisert. - */ -public class ContainerLogin { - private static final Logger LOG = LoggerFactory.getLogger(ContainerLogin.class); - - private final LoginContext loginContext; - - private OpenIDToken token; - - public ContainerLogin() { - this.loginContext = createLoginContext(); - } - - public void login() { - ensureWeHaveTokens(); - try { - loginContext.login(); - // Bakoverkompatibel. Nyere prosesstasks vil unngå ContainerLogin og heller sette kontekst direkte - KontekstHolder.setKontekst(RequestKontekst.forRequest(Systembruker.username(), IdentType.Prosess, token)); - MDCOperations.putUserId(SubjectHandler.getSubjectHandler().getUid()); - MDCOperations.putConsumerId(SubjectHandler.getSubjectHandler().getConsumerId()); - } catch (LoginException le) { - throw new TekniskException("F-499051", "Noe gikk galt ved innlogging", le); - } - } - - public void logout() { - try { - KontekstHolder.fjernKontekst(); // Skal ommøbleres ift prosesstask-dispatcher - loginContext.logout(); - } catch (LoginException e) { - LOG.warn("Noe gikk galt ved utlogging", e); - } - MDCOperations.removeUserId(); - MDCOperations.removeConsumerId(); - } - - private LoginContext createLoginContext() { - CallbackHandler callbackHandler = new CallbackHandler() { - @Override - public void handle(Callback[] callbacks) throws UnsupportedCallbackException { - for (var callback : callbacks) { - if (callback instanceof TokenCallback tokenCallback) { - tokenCallback.setToken(token); - } else { - // Should never happen - throw new UnsupportedCallbackException(callback, TokenCallback.class + " is the only supported Callback"); - } - } - } - }; - var loginContextConfiguration = new ContainerLoginConfiguration(); - String loginAppConfiguration = ContainerLoginConfiguration.LOGIN_APP_CONFIGURATION; - try { - return new LoginContext(loginAppConfiguration, new Subject(), callbackHandler, loginContextConfiguration); - } catch (LoginException le) { - throw new TekniskException("F-651753", String.format("Kunne ikke finne konfigurasjonen for %s", loginAppConfiguration), le); - } - } - - private void ensureWeHaveTokens() { - if (token == null) { - token = TokenProvider.getTokenForSystem(); - } - } - - private static class ContainerLoginConfiguration extends Configuration { - - private static final String LOGIN_APP_CONFIGURATION = "TASK_OIDC"; - private static final AppConfigurationEntry[] APP_CONFIGURATION = new AppConfigurationEntry[] { - new AppConfigurationEntry( - "no.nav.vedtak.sikkerhet.loginmodule.oidc.OIDCLoginModule", - AppConfigurationEntry.LoginModuleControlFlag.REQUISITE, - Map.of()), - new AppConfigurationEntry( - "no.nav.vedtak.sikkerhet.loginmodule.ThreadLocalLoginModule", - AppConfigurationEntry.LoginModuleControlFlag.REQUIRED, - Map.of()) - }; - - @Override - public AppConfigurationEntry[] getAppConfigurationEntry(String name) { - if (!LOGIN_APP_CONFIGURATION.equals(name)) { - throw new IllegalArgumentException("Støtter kun app configuration name: " + LOGIN_APP_CONFIGURATION); - } - return APP_CONFIGURATION; - } - } - -} diff --git a/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcAuthModuleTest.java b/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcAuthModuleTest.java index 4316f0266..a8ec0faae 100644 --- a/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcAuthModuleTest.java +++ b/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcAuthModuleTest.java @@ -32,6 +32,7 @@ import no.nav.vedtak.sikkerhet.oidc.token.OpenIDToken; import no.nav.vedtak.sikkerhet.oidc.token.TokenString; import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidator; +import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorConfig; import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorResult; public class OidcAuthModuleTest { @@ -62,7 +63,7 @@ public void setupAll() throws Exception { AzureProperty.AZURE_OPENID_CONFIG_JWKS_URI.name(), OidcTokenGenerator.ISSUER + "/jwks_uri" ); WellKnownConfigurationHelper.setWellKnownConfig(OidcTokenGenerator.ISSUER + "/" + WellKnownConfigurationHelper.STANDARD_WELL_KNOWN_PATH, JsonUtil.toJson(testData)); - OidcTokenValidatorProviderForTest.setValidators(OpenIDProvider.AZUREAD, tokenValidator); + OidcTokenValidatorConfig.addValidator(OpenIDProvider.AZUREAD, tokenValidator); } @BeforeEach diff --git a/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcTokenValidatorProviderForTest.java b/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcTokenValidatorProviderForTest.java deleted file mode 100644 index 4802a3094..000000000 --- a/felles/sikkerhet/src/test/java/no/nav/vedtak/sikkerhet/jaspic/OidcTokenValidatorProviderForTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package no.nav.vedtak.sikkerhet.jaspic; - -import no.nav.vedtak.sikkerhet.oidc.config.OpenIDProvider; -import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidator; -import no.nav.vedtak.sikkerhet.oidc.validator.OidcTokenValidatorConfig; - -public class OidcTokenValidatorProviderForTest { - - // Exposing for test - public static void setValidators(OpenIDProvider provider, OidcTokenValidator validator) { - OidcTokenValidatorConfig.addValidator(provider, validator); - } -}