Skip to content

Commit

Permalink
Flytter Jackson mapper til felles-mapper, abac til felles-abac, ny im… (
Browse files Browse the repository at this point in the history
#761)

* Flytter Jackson mapper til felles-mapper, abac til felles-abac, ny implementasjon av pdp med jersey.
  • Loading branch information
mrsladek authored Apr 19, 2021
1 parent 1e5f221 commit 3ae21be
Show file tree
Hide file tree
Showing 130 changed files with 3,505 additions and 2,226 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
with:
ref: 'master'

- name: Set up JDK 11
- name: Set up Java
uses: actions/setup-java@v2
with:
distribution: 'adopt'
Expand Down
70 changes: 70 additions & 0 deletions felles/abac/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>felles</artifactId>
<groupId>no.nav.foreldrepenger.felles</groupId>
<version>3.0.83-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>felles-abac</artifactId>
<name>Felles :: ABAC</name>
<packaging>jar</packaging>

<dependencies>
<dependency>
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-feil</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-log</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger.felles</groupId>
<artifactId>felles-mapper</artifactId>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>9.3.3</version>
<exclusions>
<exclusion>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
<version>2.4.2</version>
<exclusions>
<exclusion>
<groupId>org.ow2.asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>jakarta.interceptor</groupId>
<artifactId>jakarta.interceptor-api</artifactId>
</dependency>
<dependency>
<!-- kun for Xacml - kan erstattes ved å bytte JsonUtil til Jackson ObjectMapper -->
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-json-p-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>no.nav.foreldrepenger.felles.integrasjon</groupId>
<artifactId>felles-integrasjon-rest-klient</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package no.nav.foreldrepenger.sikkerhet.abac;

import no.nav.foreldrepenger.sikkerhet.abac.domene.AbacDataAttributter;

public interface AbacDto {
AbacDataAttributter abacAttributter();
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package no.nav.vedtak.sikkerhet.abac;
package no.nav.foreldrepenger.sikkerhet.abac;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.Function;

import no.nav.foreldrepenger.sikkerhet.abac.domene.AbacDataAttributter;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface TilpassetAbacAttributt {
public @interface AbacDtoSupplier {

Class<? extends Function<Object, AbacDataAttributter>> supplierClass();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package no.nav.vedtak.sikkerhet.abac;
package no.nav.foreldrepenger.sikkerhet.abac;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
Expand All @@ -8,17 +8,33 @@

import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding;
import javax.ws.rs.NameBinding;

import no.nav.foreldrepenger.sikkerhet.abac.domene.ActionType;
import no.nav.foreldrepenger.sikkerhet.abac.domene.ServiceType;

@Inherited
@InterceptorBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@NameBinding
public @interface BeskyttetRessurs {

/**
* Property som avgjør om bl. annet hva slags token skal brukes.
* Def fleste tjenester implementerer REST så det er default men WS will trenge SAML.
*/
@Nonbinding
ServiceType service() default ServiceType.REST;

/**
* Property som beskriver CRUD aksjon utført av tjenesten.
*/
@Nonbinding
BeskyttetRessursActionAttributt action();
ActionType action();

/**
* Ressurs type knyttet til ABAC policy man beskyttet tilgang til.
* Må ikke settes om property() brukes.
*/
@Nonbinding
String resource() default "";

Expand All @@ -37,4 +53,11 @@
*/
@Nonbinding
boolean sporingslogg() default true;

/**
* Path til tjenseten uten base_url. Brukes til sporingslogge tilgang til en konkrett tjeneste.
* Bør starte med / og være representert av @Path for alle REST tjenester eller med @Method for WS.
*/
@Nonbinding
String path();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package no.nav.foreldrepenger.sikkerhet.abac;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;

import javax.annotation.Priority;
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;

import no.nav.foreldrepenger.sikkerhet.abac.auditlog.AbacAuditlogger;
import no.nav.foreldrepenger.sikkerhet.abac.domene.AbacResultat;
import no.nav.foreldrepenger.sikkerhet.abac.domene.ActionType;
import no.nav.foreldrepenger.sikkerhet.abac.domene.BeskyttRessursAttributer;
import no.nav.foreldrepenger.sikkerhet.abac.domene.Tilgangsbeslutning;
import no.nav.foreldrepenger.sikkerhet.abac.pep.Pep;
import no.nav.foreldrepenger.sikkerhet.abac.pep.PepNektetTilgangException;
import no.nav.vedtak.exception.TekniskException;
import no.nav.vedtak.util.env.Environment;


@BeskyttetRessurs(action = ActionType.DUMMY, path = "")
@Interceptor
@Priority(Interceptor.Priority.APPLICATION + 11)
@Dependent
public class BeskyttetRessursInterceptor {

private static final Environment ENV = Environment.current();

private final Pep pep;
private final AbacAuditlogger abacAuditlogger;

@Inject
public BeskyttetRessursInterceptor(Pep pep, AbacAuditlogger abacAuditlogger) {
this.pep = pep;
this.abacAuditlogger = abacAuditlogger;
}

@AroundInvoke
public Object wrapTransaction(final InvocationContext invocationContext) throws Exception {
var attributter = hentAttributter(invocationContext);
var beslutning = pep.vurderTilgang(attributter);
if (beslutning.fikkTilgang()) {
return proceed(invocationContext, attributter, beslutning);
}
return ikkeTilgang(attributter, beslutning);
}

private BeskyttRessursAttributer hentAttributter(InvocationContext invocationContext) {
var method = invocationContext.getMethod();
var beskyttetRessurs = method.getAnnotation(BeskyttetRessurs.class);

var attributter = new BeskyttRessursAttributer()
.setServiceType(beskyttetRessurs.service())
.setActionType(beskyttetRessurs.action())
.setRequestPath(beskyttetRessurs.path());

if (!beskyttetRessurs.property().isEmpty()) {
var resource = ENV.getProperty(beskyttetRessurs.property());
attributter.setResource(resource);
} else if (!beskyttetRessurs.resource().isEmpty()) {
attributter.setResource(beskyttetRessurs.resource());
}

// Legg på alle attributer fra AbacDtoer og AbacDtoSupplier
var parameterDecl = method.getParameters();
for (int i = 0; i < method.getParameterCount(); i++) {
Object parameterValue = invocationContext.getParameters()[i];
AbacDtoSupplier supplierAnnoterign = parameterDecl[i].getAnnotation(AbacDtoSupplier.class);
leggTilAttributterFraParameter(attributter, parameterValue, supplierAnnoterign);
}
return attributter;
}

@SuppressWarnings("rawtypes")
static void leggTilAttributterFraParameter(BeskyttRessursAttributer attributter, Object parameterValue, AbacDtoSupplier supplierAnnotering) {
if (supplierAnnotering != null) {
leggTil(attributter, supplierAnnotering, parameterValue);
} else {
if (parameterValue instanceof AbacDto) { // NOSONAR for å støtte både enkelt-DTO-er og collection av DTO-er
attributter.leggTil(((AbacDto) parameterValue).abacAttributter());
} else if (parameterValue instanceof Collection) { // NOSONAR for å støtte både enkelt-DTO-er og collection av DTO-er
leggTilAbacDtoSamling(attributter, (Collection) parameterValue);
}
}
}

private static void leggTilAbacDtoSamling(BeskyttRessursAttributer attributter, Collection<?> parameterValue) {
for (Object value : parameterValue) {
if (value instanceof AbacDto) {
attributter.leggTil(((AbacDto) value).abacAttributter());
} else {
throw new TekniskException("F-261962",
String.format("Ugyldig input forventet at samling inneholdt bare AbacDto-er, men fant %s",
value != null ? value.getClass().getName() : "null"));
}
}
}

private static void leggTil(BeskyttRessursAttributer attributter, AbacDtoSupplier abacDtoSupplier, Object verdi) {
try {
var dataAttributter = abacDtoSupplier.supplierClass().getDeclaredConstructor().newInstance().apply(verdi);
attributter.leggTil(dataAttributter);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException e) {
throw new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw new IllegalStateException(e.getCause());
}
}

private Object proceed(InvocationContext invocationContext, BeskyttRessursAttributer attributter, Tilgangsbeslutning beslutning) throws Exception {
Method method = invocationContext.getMethod();
boolean auditlogges = method.getAnnotation(BeskyttetRessurs.class).sporingslogg();
if (auditlogges) {
abacAuditlogger.loggTilgang(beslutning.getPdpRequest(), attributter);
return invocationContext.proceed();
}
return invocationContext.proceed();
}

private Object ikkeTilgang(BeskyttRessursAttributer attributter, Tilgangsbeslutning beslutning) {
abacAuditlogger.loggDeny(beslutning.getPdpRequest(), attributter);

switch (beslutning.getBeslutningKode()) {
case AVSLÅTT_KODE_6: throw new PepNektetTilgangException("F-709170", "Tilgangskontroll.Avslag.Kode6");
case AVSLÅTT_KODE_7: throw new PepNektetTilgangException("F-027901", "Tilgangskontroll.Avslag.Kode7");
case AVSLÅTT_EGEN_ANSATT: throw new PepNektetTilgangException("F-788257", "Tilgangskontroll.Avslag.EgenAnsatt");
default: throw new PepNektetTilgangException("F-608625", "Ikke tilgang");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package no.nav.foreldrepenger.sikkerhet.abac;

import no.nav.foreldrepenger.sikkerhet.abac.domene.BeskyttRessursAttributer;
import no.nav.foreldrepenger.sikkerhet.abac.pep.PdpRequest;

public interface PdpRequestBuilder {
PdpRequest lagPdpRequest(BeskyttRessursAttributer attributter);
}
Loading

0 comments on commit 3ae21be

Please sign in to comment.