Code Monkey home page Code Monkey logo

bidrag-commons's Introduction

bidrag-commons

Komponenter som brukes på tvers av applikasjoner under bidrag

Det finnes et annet felles-bibliotek (bidrag-commons-test) som utelukkende er laget for å gjenbruke komponenter til enhetstesting.

Innhold

Sikkerhetskonfigurasjon

Sikkerhetskonfigurasjon er et enkel wrapper av NAV sin sikkerhetsbibliotek token-support.
Det er lagt støtte for validering av Authorization token i kallet gjennom token-validation-spring og generering av token med caching gjennom token-client-spring.

Sikkerhetskonfigurasjon kan "skrus" på ved å legge til annotering @EnableSecurityConfiguration i konfigurasjonen.
I tillegg må SecurityAutoConfiguration og ManagementWebSecurityAutoConfiguration "excludes" da de blir dratt automatisk inn gjennom Spring web konfigurasjon. Disse bibliotekene konfigurer basic Spring sikkerhetskonfigurasjon (basic auth med brukernavn/passord) som ikke er nødvendig da vi gjør vår egen validering av token.

Eksempel på hvordan det kan konfigureres

@SpringBootApplication(exclude = [SecurityAutoConfiguration::class, ManagementWebSecurityAutoConfiguration::class])
@EnableSecurityConfiguration 
class BidragApplication

fun main() {
    SpringApplication.run(BidragApplication::class.java)
}

I tillegg må det under legges til i application.yaml:

no.nav.security.jwt:
  sts: #<--- Hvis STS token skal brukes ved videre kall mot andre apper. Ellers trenger ikke dette å settes
    properties:
      url: ${SECURITY_TOKEN_URL}
      username: ${SRVBIDRAG_USERNAME}
      password: ${SRVBIDRAG_PASSWORD}
  client:
    registration:
      app1:
        token-endpoint-url: https://login.microsoftonline.com/${AZURE_APP_TENANT_ID}/oauth2/v2.0/token
        grant-type: client_credentials #<--- Hvis det er service-service kall og kall videre skal gjøres med applikasjonstoken
        scope: api://${APP1_SCOPE}/.default
        authentication:
          client-id: ${AZURE_APP_CLIENT_ID}
          client-secret: ${AZURE_APP_CLIENT_SECRET}
          client-auth-method: client_secret_post
     app2:
        token-endpoint-url: https://login.microsoftonline.com/${AZURE_APP_TENANT_ID}/oauth2/v2.0/token
        grant-type: urn:ietf:params:oauth:grant-type:jwt-bearer #<--- Hvis kallet gjøres i kontekst av en bruker. Vil da generere on-behalf-of token basert på input token.
        scope: api://${APP2_SCOPE}/.default
        authentication:
          client-id: ${AZURE_APP_CLIENT_ID}
          client-secret: ${AZURE_APP_CLIENT_SECRET}
          client-auth-method: client_secret_post
  issuer:
    isso: #<--- Hvis du forventer ISSO token i input. Ellers kan dette ignoreres
      acceptedaudience: ${ISSO_ACCEPTED_AUDIENCE}
      discoveryurl: ${ISSO_ISSUER_URL}/.well-known/openid-configuration
    sts: #<--- Hvis du forventer STS token i input. Ellers kan dette ignoreres
      acceptedaudience: ${STS_ACCEPTED_AUDIENCE}
      discoveryurl: ${STS_ISSUER_URL}/.well-known/openid-configuration
    aad: #<--- Hvis du forventer Azure token i input. Dette må settes hvis du har RestKontroller
      discovery_url: https://login.microsoftonline.com/${AZURE_APP_TENANT_ID}/v2.0/.well-known/openid-configuration
      accepted_audience: ${AZURE_APP_CLIENT_ID}, api://${AZURE_APP_CLIENT_ID}

Restemplate kan da konfigureres ved å bruke SecurityTokenService bønne som blir eksponert gjennom sikkerhetskonfigurasjonen. Interceptorene legger til Authorization header til kallet med sikkerhetstoken.

/**
 * securityTokenService.serviceUserAuthTokenIntercepton("appname") vil generere clienbt_credentials token
 */
@Bean
fun app1Consumer(
    @Value("\${APP1_URL}") app1Url: String,
    restTemplate: HttpHeaderRestTemplate, 
    securityTokenService: SecurityTokenService
): OppgaveConsumer {
    restTemplate.uriTemplateHandler = RootUriTemplateHandler(app1Url)
    restTemplate.interceptors.add(securityTokenService.serviceUserAuthTokenInterceptor("app1"))
    return DefaultOppgaveConsumer(restTemplate)
}

/**
 * securityTokenService.authTokenInterceptor("appname") vil generere token basert på input.
 * Hvis input inneholder applikasjon token så vil det genereres client_credentials token. Ellers vil det genereres on-behalf-of token fra input.
 */
@Bean
fun app2Consumer(
    @Value("\${APP2_URL}") app2Url: String,
    restTemplate: HttpHeaderRestTemplate,
    securityTokenService: SecurityTokenService
): OppgaveConsumer {
    restTemplate.uriTemplateHandler = RootUriTemplateHandler(app1Url)
    restTemplate.interceptors.add(securityTokenService.authTokenInterceptor("app2Url"))
    return DefaultOppgaveConsumer(restTemplate)
}

HttpHeaderRestTemplate

Implementasjon av RestTemplate med noe ekstra funksjonalitet.

addHeaderGenerator kan brukes til å legge til Header på kallet på enkel måte.

withDefaultHeaders legger til X-Enhet og X-Correlation-ID headere til kallet.
Dette hentes fra LocalThread som blir lagt til i EnhetFilter og CorrelationIdFilter og bør derfor brukes i kombinasjon av filterne

SensitiveLogMasker

Vil maskere aktørid og fnr fra logg meldingene. Dette kan konfigureres ved å oppdatere logback filen:

  <appender name="stdout_json" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
      <providers>
        <mdc/>
        <timestamp/>
        <message/>
        <loggerName/>
        <threadName/>
        <logLevel/>
        <callerData/>
        <arguments/>
        <stackTrace/>
      </providers>
      ----> Legg til følgende i logback filen
      <jsonGeneratorDecorator class="net.logstash.logback.mask.MaskingJsonGeneratorDecorator">
        <valueMasker class="no.nav.bidrag.commons.logging.SensitiveLogMasker"/>
      </jsonGeneratorDecorator>
    </encoder>
  </appender>

Web filter

Dette biblioteket inneholder to filtere.

Det ene er EnhetFilter som leser X-Enhet header fra kallet og lagrer det i MDC

Bruker cache

Hvis en tjeneste tilbyr tilgangstyrt data som krever spesiell tilgang for å aksessere kan det være dumt å bruke generell cache. Da kan en person uten tilgang kunne aksessere data fordi cachen ikke gjør noe tilgangskontroll på bruker som kaller tjenesten. Eksempel på dette er caching av respons fra bidrag-person. Hvis en bruker/applikasjon henter data om en kode 6/7 bruker som caches vil neste person uten tilgang kunne aksessere samme data fordi den hentes fra cachen istedenfor PDL. For å unngå dette problemet bør @BrukerCacheable brukes. Denne annoteringen henter saksbehandlerident fra token i kontekst og bruker den når nøkkel for cachen opprettes. Cachen blir da begrenset til bruker istedenfor å være generell. Hvis det er en applikasjon som kaller tjenesten så vil en felles nøkkel brukes. For at @BrukerCacheable annotering skal fungere må @Import(BrukerCacheKonfig::class) annotering legges til på Cache konfigurasjonen

@Configuration
@EnableCaching
@Import(BrukerCacheKonfig::class) <----
class CacheConfig {
....

Deretter kan bruker cache brukes på følgende måte

  @BrukerCacheable("personinfo")
  fun hentPersonInfo(ident: String): PersonDto {
    return PersonDto()
  }

Invalider cache før starten av arbeidsdag

Hvis du bruker CaffeineCacheManager kan følgende brukes for å konfigurere cache slik at den invalideres/slettes før starten av arbeisdagen (Kl 06.00 hver dag)

  @Bean
    fun cacheManager(): CacheManager {
        val caffeineCacheManager = CaffeineCacheManager()
        caffeineCacheManager.registerCustomCache(PERSON_CACHE, Caffeine.newBuilder().expireAfter(InvaliderCacheFørStartenAvArbeidsdag()).build())
        return caffeineCacheManager
    }

continuous integration and deployment

Gjøres med 'workflows' og 'actions' fra GitHub. Ny pakker bygges og reslease ved merge til main i github.

bidrag-commons's People

Contributors

bent-lorentzen avatar dependabot[bot] avatar jactor-rises avatar larsottohaugen avatar rinnan17 avatar s148719 avatar simhos avatar snyk-bot avatar ugur93 avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.