From 332478fe3c16f46cf11ed1f9f3535b2ce0fb01c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steffen=20P=C3=B8hner?= Date: Thu, 8 Aug 2024 11:55:51 +0200 Subject: [PATCH] Saksbehandlerprofil: bytt fra ldap til fp-tilgang som kilde (#2101) --- .deploy/dev-fss-teamforeldrepenger.json | 1 - .deploy/naiserator.yaml | 2 - .deploy/prod-fss-teamforeldrepenger.json | 1 - .../organisasjon/ansatt/AnsattTjeneste.java | 37 +----- .../ansatt/LdapBrukeroppslag.java | 113 ------------------ .../organisasjon/ansatt/LdapInnlogging.java | 54 --------- .../dto/ReservasjonStatusDtoTjeneste.java | 2 +- .../felles/dto/SaksbehandlerDtoTjeneste.java | 4 +- .../resources/application-dev-fss.properties | 7 -- .../resources/application-prod-fss.properties | 7 -- src/test/resources/application-vtp.properties | 5 - 11 files changed, 5 insertions(+), 228 deletions(-) delete mode 100644 src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapBrukeroppslag.java delete mode 100644 src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapInnlogging.java diff --git a/.deploy/dev-fss-teamforeldrepenger.json b/.deploy/dev-fss-teamforeldrepenger.json index e1e7ee703..82485696e 100644 --- a/.deploy/dev-fss-teamforeldrepenger.json +++ b/.deploy/dev-fss-teamforeldrepenger.json @@ -4,7 +4,6 @@ "oracleconfigkv": "/oracle/data/dev/config/fplos_q1", "oraclecredskv": "/oracle/data/dev/creds/fplos_q1-fplos_q1", "serviceuserkv": "/serviceuser/data/dev/srvfplos", - "ldapuserkv": "/serviceuser/data/dev/srvssolinux", "ingresses": [ "https://fplos.dev-fss-pub.nais.io" ], diff --git a/.deploy/naiserator.yaml b/.deploy/naiserator.yaml index 7db81db54..09e0db53b 100644 --- a/.deploy/naiserator.yaml +++ b/.deploy/naiserator.yaml @@ -54,8 +54,6 @@ spec: mountPath: /var/run/secrets/nais.io/defaultDSconfig - kvPath: {{serviceuserkv}} mountPath: /var/run/secrets/nais.io/serviceuser - - kvPath: {{ldapuserkv}} - mountPath: /var/run/secrets/nais.io/ldap azure: application: enabled: true diff --git a/.deploy/prod-fss-teamforeldrepenger.json b/.deploy/prod-fss-teamforeldrepenger.json index 41ae27cc3..7879e4357 100644 --- a/.deploy/prod-fss-teamforeldrepenger.json +++ b/.deploy/prod-fss-teamforeldrepenger.json @@ -4,7 +4,6 @@ "oracleconfigkv": "/oracle/data/prod/config/fplos_p", "oraclecredskv": "/oracle/data/prod/creds/fplos_p-fplos_p", "serviceuserkv": "/serviceuser/data/prod/srvfplos", - "ldapuserkv": "/serviceuser/data/prod/srvssolinux", "ingresses": [ "https://fplos.prod-fss-pub.nais.io" ], diff --git a/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/AnsattTjeneste.java b/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/AnsattTjeneste.java index d1f1f7379..dd3c5c691 100644 --- a/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/AnsattTjeneste.java +++ b/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/AnsattTjeneste.java @@ -1,14 +1,10 @@ package no.nav.foreldrepenger.los.organisasjon.ansatt; -import java.time.Duration; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import no.nav.foreldrepenger.los.domene.typer.aktør.OrganisasjonsEnhet; @@ -19,8 +15,6 @@ @ApplicationScoped public class AnsattTjeneste { - private static final Logger LOG = LoggerFactory.getLogger(AnsattTjeneste.class); - private static final LRUCache ANSATT_PROFIL = new LRUCache<>(1000, TimeUnit.MILLISECONDS.convert(24 * 7, TimeUnit.HOURS)); private static final LRUCache> ANSATT_ENHETER = new LRUCache<>(1000, TimeUnit.MILLISECONDS.convert(25, TimeUnit.HOURS)); private static final Map ENHETSNUMMER_AVDELINGSNAVN_MAP = new HashMap<>(); @@ -30,8 +24,6 @@ public class AnsattTjeneste { private List aktuelleEnhetIder; - - AnsattTjeneste() { // for CDI proxy } @@ -48,37 +40,12 @@ public BrukerProfil hentBrukerProfil(String ident) { if (ANSATT_PROFIL.get(ident) == null) { //TODO: Her bør vi egentlig tenke om NOM er ikke riktigere å bruke - bør være raskere å slå opp navn og epost. // Jeg har sjekket med NOM (01.07.2024) og de støtter en så lenge ikke Z-identer i dev. Men prod brukere er tilgjengelig. - var før = System.nanoTime(); - var ldapRespons = new LdapBrukeroppslag().hentBrukerProfil(ident); - LOG.info("LDAP bruker profil oppslag: {}ms. ", Duration.ofNanos(System.nanoTime() - før).toMillis()); - var ansattEnhet = avdeling(ldapRespons.ansattEnhet()); - if (ansattEnhet == null) { - LOG.info("PROFIL LDAP: brukers enhet {} ikke blant saksbehandlingsenhetene", ldapRespons.ansattEnhet()); - } - var brukerProfil = new BrukerProfil(ldapRespons.ident(), ldapRespons.navn(), ldapRespons.fornavnEtternavn(), ldapRespons.epostAdresse(), - ansattEnhet); - sammenlignMedAzureGraphFailSoft(ident, brukerProfil); + var brukerProfil = mapTilDomene(new AzureBrukerKlient().brukerProfil(ident)); ANSATT_PROFIL.put(ident, brukerProfil); } return ANSATT_PROFIL.get(ident); } - private static void sammenlignMedAzureGraphFailSoft(String ident, BrukerProfil ldapBrukerInfo) { - LOG.info("PROFIL Azure. Henter fra azure."); - try { - var før = System.nanoTime(); - var azureBrukerProfil = mapTilDomene(new AzureBrukerKlient().brukerProfil(ident)); - if (!ldapBrukerInfo.equals(azureBrukerProfil)) { - LOG.info("PROFIL Azure. Profiler fra ldap og azure er ikke like. Azure: {} != LDAP: {}", azureBrukerProfil, ldapBrukerInfo); - } else { - LOG.info("PROFIL Azure. Azure == LDAP :)"); - } - LOG.info("Azure bruker profil oppslag: {}ms. ", Duration.ofNanos(System.nanoTime() - før).toMillis()); - } catch (Exception ex) { - LOG.info("PROFIL Azure. Klienten feilet med exception: {}", ex.getMessage()); - } - } - public List hentAvdelingerNavnForAnsatt(String ident) { if (aktuelleEnhetIder == null) { aktuelleEnhetIder = organisasjonRepository.hentAktiveAvdelinger().stream().map(Avdeling::getAvdelingEnhet).toList(); @@ -96,7 +63,7 @@ public List hentAvdelingerNavnForAnsatt(String ident) { } private static BrukerProfil mapTilDomene(AzureBrukerKlient.BrukerProfilResponse klientResponse) { - return new BrukerProfil(klientResponse.ident(), klientResponse.navn(), klientResponse.fornavnEtternavn(), klientResponse.epost(), + return new BrukerProfil(klientResponse.ident(), klientResponse.fornavnEtternavn(), klientResponse.fornavnEtternavn(), klientResponse.epost(), avdeling(klientResponse.ansattVedEnhetId())); } diff --git a/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapBrukeroppslag.java b/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapBrukeroppslag.java deleted file mode 100644 index 027376dd6..000000000 --- a/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapBrukeroppslag.java +++ /dev/null @@ -1,113 +0,0 @@ -package no.nav.foreldrepenger.los.organisasjon.ansatt; - -import java.util.regex.Pattern; - -import javax.naming.InvalidNameException; -import javax.naming.LimitExceededException; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.SearchControls; -import javax.naming.directory.SearchResult; -import javax.naming.ldap.LdapContext; -import javax.naming.ldap.LdapName; - -import no.nav.vedtak.exception.IntegrasjonException; -import no.nav.vedtak.exception.TekniskException; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - - -public class LdapBrukeroppslag { - - private static final Logger LOG = LoggerFactory.getLogger(LdapBrukeroppslag.class); - private static final Pattern IDENT_PATTERN = Pattern.compile("^\\p{LD}+$"); - - private final LdapContext context; - private final LdapName searchBase; - private static final String GIVEN_NAME = "givenName"; - private static final String SURNAME = "sn"; - private static final String USER_PRINCIPAL_NAME = "userPrincipalName"; - private static final String STREET_ADDRESS = "streetAddress"; - private static final String DISPLAY_NAME_ATTR = "displayName"; - - public LdapBrukeroppslag() { - this(LdapInnlogging.lagLdapContext(), lagLdapSearchBase()); - } - - LdapBrukeroppslag(LdapContext context, LdapName searcBase) { - this.context = context; - this.searchBase = searcBase; - } - - public BrukerProfilRespons hentBrukerProfil(String ident) { - var result = ldapSearch(ident.trim()); - var displayName = find(result, DISPLAY_NAME_ATTR); - var givenName = find(result, GIVEN_NAME); - var surname = find(result, SURNAME); - var upn = find(result, USER_PRINCIPAL_NAME); - var addressCode = find(result, STREET_ADDRESS); - try { - var fornavn = givenName.get().toString(); - var etternavn = surname.get().toString(); - var fornavnEtternavn = fornavn + " " + etternavn; - var navn = displayName.get().toString(); - var epostAdresse = upn.get().toString(); - var ansattKontornummer = addressCode.get().toString(); - if (!epostAdresse.contains("@nav.no")) { - LOG.info("LDAP: fant ikke gyldig epostadresse for bruker {}", ident); - } - return new BrukerProfilRespons(ident, navn, fornavnEtternavn, epostAdresse, ansattKontornummer); - } catch (NamingException e) { - throw new TekniskException("F-314006", String.format("Kunne ikke hente ut attributtverdi for ident %s", ident), e); - } - } - - private SearchResult ldapSearch(String ident) { - if (ident == null || ident.isEmpty()) { - throw new TekniskException("F-344885", "Kan ikke slå opp brukernavn uten å ha ident"); - } - var matcher = IDENT_PATTERN.matcher(ident); - if (!matcher.matches()) { - throw new TekniskException("F-271934", String.format("Mulig LDAP-injection forsøk. Søkte med ugyldig ident '%s'", ident)); - } - - var controls = new SearchControls(); - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); - controls.setCountLimit(1); - controls.setReturningAttributes(new String[]{DISPLAY_NAME_ATTR, GIVEN_NAME, SURNAME, USER_PRINCIPAL_NAME, STREET_ADDRESS}); - var søkestreng = String.format("(cn=%s)", ident); - try { - var result = context.search(searchBase, søkestreng, controls); // NOSONAR - if (result.hasMoreElements()) { - return result.nextElement(); - } - throw new IntegrasjonException("F-418891", String.format("Fikk ingen treff på søk mot LDAP etter ident %s", ident)); - } catch (LimitExceededException lee) { - throw new IntegrasjonException("F-137440", - String.format("Forventet ett unikt resultat på søk mot LDAP etter ident %s, men fikk flere treff", ident), lee); - } catch (NamingException e) { - throw new IntegrasjonException("F-690609", String.format("Uventet feil ved LDAP-søk %s", søkestreng), e); - } - } - - private static Attribute find(SearchResult element, String attributeName) { - var attribute = element.getAttributes().get(attributeName); - if (attribute == null) { - throw new IntegrasjonException("F-828846", String.format("Resultat fra LDAP manglet påkrevet attributtnavn %s", attributeName)); - } - return attribute; - } - - private static LdapName lagLdapSearchBase() { - var userBaseDn = LdapInnlogging.getRequiredProperty("ldap.user.basedn"); - try { - return new LdapName(userBaseDn); // NOSONAR - } catch (InvalidNameException e) { - throw new IntegrasjonException("F-703197", String.format("Kunne ikke definere base-søk mot LDAP %s", userBaseDn), e); - } - } - - public record BrukerProfilRespons(String ident, String navn, String fornavnEtternavn, String epostAdresse, String ansattEnhet) { } - -} diff --git a/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapInnlogging.java b/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapInnlogging.java deleted file mode 100644 index f100214c5..000000000 --- a/src/main/java/no/nav/foreldrepenger/los/organisasjon/ansatt/LdapInnlogging.java +++ /dev/null @@ -1,54 +0,0 @@ -package no.nav.foreldrepenger.los.organisasjon.ansatt; - -import no.nav.foreldrepenger.konfig.Environment; -import no.nav.vedtak.exception.TekniskException; - -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.ldap.InitialLdapContext; -import javax.naming.ldap.LdapContext; - -import java.util.Hashtable; - -import static java.lang.String.format; - -public class LdapInnlogging { - - private static final Environment ENV = Environment.current(); - - private LdapInnlogging() { - throw new IllegalArgumentException("skal ikke instansieres"); - } - - public static LdapContext lagLdapContext() { - String authMode = ENV.getProperty("ldap.auth", "simple"); - String url = getRequiredProperty("ldap.url"); - - Hashtable environment = new Hashtable<>(); // NOSONAR //metodeparameter krever Hashtable - environment.put(Context.INITIAL_CONTEXT_FACTORY, ENV.getProperty("ldap.ctxfactory", "com.sun.jndi.ldap.LdapCtxFactory")); - environment.put(Context.PROVIDER_URL, url); - environment.put(Context.SECURITY_AUTHENTICATION, authMode); - - if ("simple".equals(authMode)) { - String user = getRequiredProperty("ldap.username") + "@" + getRequiredProperty("ldap.domain"); - environment.put(Context.SECURITY_CREDENTIALS, getRequiredProperty("ldap.password")); - environment.put(Context.SECURITY_PRINCIPAL, user); - } else if ("none".equals(authMode)) { - // do nothing - } else { - // støtter ikke [java.naming.security.authentication]="strong" eller andre. - // Ignorerer også foreløpig. - } - - try { - return new InitialLdapContext(environment, null); - } catch (NamingException e) { - throw new TekniskException("F-222862", String.format("Klarte ikke koble til LDAP på URL %s", url)); - } - } - - static String getRequiredProperty(String key) { - return ENV.getRequiredProperty(key, - () -> new TekniskException("F-055498", format("Klarte ikke koble til LDAP da påkrevd prroperty %s ikke er satt", key))); - } -} diff --git a/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/ReservasjonStatusDtoTjeneste.java b/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/ReservasjonStatusDtoTjeneste.java index a797134bd..533bf8a74 100644 --- a/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/ReservasjonStatusDtoTjeneste.java +++ b/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/ReservasjonStatusDtoTjeneste.java @@ -44,7 +44,7 @@ private String hentNavn(String ident) { if (ident == null) { return null; } - return tryOrEmpty(() -> ansattTjeneste.hentBrukerProfil(ident), "ldap") + return tryOrEmpty(() -> ansattTjeneste.hentBrukerProfil(ident), "brukerprofil") .map(BrukerProfil::navn) .orElse("Ukjent"); } diff --git a/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/SaksbehandlerDtoTjeneste.java b/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/SaksbehandlerDtoTjeneste.java index c4e228112..cdd7cabd1 100644 --- a/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/SaksbehandlerDtoTjeneste.java +++ b/src/main/java/no/nav/foreldrepenger/los/tjenester/felles/dto/SaksbehandlerDtoTjeneste.java @@ -67,9 +67,9 @@ private Optional tilSaksbehandlerMedAvdelingerDto } public SaksbehandlerMedAvdelingerDto lagKjentOgUkjentSaksbehandlerMedAvdelingerDto(Saksbehandler saksbehandler) { - // saksbehandler kan eksistere i basen men være ukjent i ldap + // saksbehandler kan eksistere i basen men være ukjent i azuread var ident = saksbehandler.getSaksbehandlerIdent(); - var saksbehandlerDto = tilSaksbehandlerDto(ident); + var saksbehandlerDto = tilSaksbehandlerDto(ident.toLowerCase()); if (saksbehandlerDto.isPresent()) { var avdelinger = ansattTjeneste.hentAvdelingerNavnForAnsatt(ident); return new SaksbehandlerMedAvdelingerDto(saksbehandlerDto.get(), avdelinger); diff --git a/src/main/resources/application-dev-fss.properties b/src/main/resources/application-dev-fss.properties index 5b1dcbd97..a753abbbe 100644 --- a/src/main/resources/application-dev-fss.properties +++ b/src/main/resources/application-dev-fss.properties @@ -1,10 +1,3 @@ -# LDAP -ldap.url=ldaps://ldapgw.preprod.local -ldap.basedn=dc=preprod,dc=local -ldap.domain=PREPROD.LOCAL -ldap.user.basedn=ou=NAV,ou=BusinessUnits,dc=preprod,dc=local -ldap.serviceuser.basedn=ou=ServiceAccounts,dc=preprod,dc=local - # Database # defaultDS.username= # defaultDS.password= diff --git a/src/main/resources/application-prod-fss.properties b/src/main/resources/application-prod-fss.properties index 30828a7ae..f1610d47c 100644 --- a/src/main/resources/application-prod-fss.properties +++ b/src/main/resources/application-prod-fss.properties @@ -1,10 +1,3 @@ -# LDAP -ldap.url=ldaps://ldapgw.adeo.no -ldap.basedn=dc=adeo,dc=no -ldap.domain=ADEO.NO -ldap.user.basedn=ou=NAV,ou=BusinessUnits,dc=adeo,dc=no -ldap.serviceuser.basedn=ou=ServiceAccounts,dc=adeo,dc=no - # Database # defaultDS.username= # defaultDS.password= diff --git a/src/test/resources/application-vtp.properties b/src/test/resources/application-vtp.properties index eba6b58ff..3f2115ff8 100644 --- a/src/test/resources/application-vtp.properties +++ b/src/test/resources/application-vtp.properties @@ -34,11 +34,6 @@ azure.app.well.known.url=http://authserver:8060/rest/azuread/.well-known/openid- AZURE_APP_CLIENT_ID=vtp NAIS_CLUSTER_NAME=vtp -# LDAP -ldap.url=ldap://localhost:8389/ -ldap.auth=none -ldap.user.basedn=ou\=NAV,ou\=BusinessUnits,dc\=test,dc\=local - task.manager.polling.wait=5 task.manager.polling.delay=5 task.manager.polling.tasks.size=1