Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Branch for å bygge versjon 2 av felles med token-support 3.2.0 for de som fortsatt bruker spring 3.1.x og som trenger å få ut en bugfix i felles som skal ut i disse prosjektene. All kode som merges inn i denne branchen vil lage en versjon 2.x #781

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/build-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,15 @@ jobs:
env:
GITHUB_USERNAME: x-access-token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: github.base_ref == 'main' && github.event.pull_request.merged == true
run: |
export GIT_COMMIT_HASH=$(git log -n 1 --pretty=format:'%h')
export GIT_COMMIT_DATE=$(git log -1 --pretty='%ad' --date=format:'%Y%m%d%H%M%S')
export VERSION=3.${GIT_COMMIT_DATE}_${GIT_COMMIT_HASH}
export VERSION=2.${GIT_COMMIT_DATE}_${GIT_COMMIT_HASH}
echo "Setting version $VERSION"
mvn --settings .m2/maven-settings.xml versions:set -DnewVersion="$VERSION"
mvn --settings .m2/maven-settings.xml versions:commit

- name: Deploy to Github Package
if: github.base_ref == 'main' && github.event.pull_request.merged == true
env:
GITHUB_USERNAME: x-access-token
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ import no.nav.security.token.support.client.core.http.OAuth2HttpRequest
import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenResponse
import no.nav.security.token.support.client.spring.oauth2.DefaultOAuth2HttpClient
import org.slf4j.LoggerFactory
import org.springframework.boot.web.client.RestTemplateBuilder
import org.springframework.core.NestedExceptionUtils
import org.springframework.web.client.HttpServerErrorException
import org.springframework.web.client.RestClient
import java.net.SocketException
import java.net.SocketTimeoutException

class RetryOAuth2HttpClient(
restClient: RestClient,
restTemplateBuilder: RestTemplateBuilder,
private val maxRetries: Int = 2,
) : DefaultOAuth2HttpClient(restClient) {
) : DefaultOAuth2HttpClient(restTemplateBuilder) {
private val logger = LoggerFactory.getLogger(javaClass)
private val secureLogger = LoggerFactory.getLogger("secureLogger")

Expand All @@ -25,7 +25,7 @@ class RetryOAuth2HttpClient(
HttpServerErrorException.BadGateway::class,
)

override fun post(oAuth2HttpRequest: OAuth2HttpRequest): OAuth2AccessTokenResponse {
override fun post(oAuth2HttpRequest: OAuth2HttpRequest): OAuth2AccessTokenResponse? {
var retries = 0

while (true) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package no.nav.familie.http.interceptor

import com.nimbusds.oauth2.sdk.GrantType
import no.nav.familie.http.sts.StsRestClient
import no.nav.security.token.support.client.core.ClientProperties
import no.nav.security.token.support.client.core.OAuth2GrantType
import no.nav.security.token.support.client.core.oauth2.OAuth2AccessTokenService
import no.nav.security.token.support.client.spring.ClientConfigurationProperties
import no.nav.security.token.support.core.exceptions.JwtTokenValidatorException
import no.nav.security.token.support.spring.SpringTokenValidationContextHolder
import org.springframework.http.HttpRequest
import org.springframework.http.client.ClientHttpRequestExecution
Expand Down Expand Up @@ -53,7 +51,7 @@ class BearerTokenClientCredentialsClientInterceptor(
request,
clientConfigurationProperties,
oAuth2AccessTokenService,
GrantType.CLIENT_CREDENTIALS,
OAuth2GrantType.CLIENT_CREDENTIALS,
),
)
return execution.execute(request, body)
Expand Down Expand Up @@ -137,17 +135,15 @@ private fun genererAccessToken(
request: HttpRequest,
clientConfigurationProperties: ClientConfigurationProperties,
oAuth2AccessTokenService: OAuth2AccessTokenService,
grantType: GrantType? = null,
grantType: OAuth2GrantType? = null,
): String {
val clientProperties =
clientPropertiesFor(
request.uri,
clientConfigurationProperties,
grantType,
)
return oAuth2AccessTokenService.getAccessToken(
clientProperties,
).accessToken ?: throw JwtTokenValidatorException("Kunne ikke hente accesstoken")
return oAuth2AccessTokenService.getAccessToken(clientProperties).accessToken
}

/**
Expand All @@ -160,7 +156,7 @@ private fun genererAccessToken(
private fun clientPropertiesFor(
uri: URI,
clientConfigurationProperties: ClientConfigurationProperties,
grantType: GrantType?,
grantType: OAuth2GrantType?,
): ClientProperties {
val clientProperties = filterClientProperties(clientConfigurationProperties, uri)
return if (grantType == null) {
Expand All @@ -184,7 +180,7 @@ private fun filterClientProperties(

private fun clientPropertiesForGrantType(
values: List<ClientProperties>,
grantType: GrantType,
grantType: OAuth2GrantType,
uri: URI,
): ClientProperties {
return values.firstOrNull { grantType == it.grantType }
Expand All @@ -196,7 +192,7 @@ private fun clientCredentialOrJwtBearer() = if (erSystembruker()) OAuth2GrantTyp
private fun erSystembruker(): Boolean {
return try {
val preferredUsername =
SpringTokenValidationContextHolder().getTokenValidationContext().getClaims("azuread").get("preferred_username")
SpringTokenValidationContextHolder().tokenValidationContext.getClaims("azuread")["preferred_username"]
return preferredUsername == null
} catch (e: Throwable) {
// Ingen request context. Skjer ved kall som har opphav i kjørende applikasjon. Ping etc.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,18 @@ import org.junit.jupiter.api.AfterAll
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.springframework.boot.web.client.ClientHttpRequestFactories
import org.springframework.boot.web.client.ClientHttpRequestFactorySettings
import org.springframework.web.client.RestClient
import org.springframework.boot.web.client.RestTemplateBuilder
import java.net.URI
import java.time.Duration
import java.time.temporal.ChronoUnit

internal class RetryOAuth2HttpClientTest {
val clientHttpRequestFactorySettings =
ClientHttpRequestFactorySettings.DEFAULTS
.withConnectTimeout(Duration.of(1, ChronoUnit.SECONDS))
.withReadTimeout(Duration.of(1, ChronoUnit.SECONDS))
private val restTemplateBuilder =
RestTemplateBuilder()
.setConnectTimeout(Duration.of(1, ChronoUnit.SECONDS))
.setReadTimeout(Duration.of(1, ChronoUnit.SECONDS))

val requestFactory = ClientHttpRequestFactories.get(clientHttpRequestFactorySettings)
val restClient =
RestClient.builder()
.requestFactory(requestFactory)
.build()
val client = RetryOAuth2HttpClient(restClient)
private val client = RetryOAuth2HttpClient(restTemplateBuilder)

@BeforeEach
internal fun setUp() {
Expand All @@ -46,21 +39,21 @@ internal class RetryOAuth2HttpClientTest {

@Test
internal fun `404 - skal kun kalle en gang`() {
stub(WireMock.notFound())
stub(WireMock.serverError().withStatus(404))
post()
wireMockServer.verify(1, RequestPatternBuilder.allRequests())
}

@Test
internal fun `503 - skal prøve på nytt`() {
stub(WireMock.serviceUnavailable())
stub(WireMock.aResponse().withStatus(503))
post()
wireMockServer.verify(2, RequestPatternBuilder.allRequests())
}

@Test
internal fun `502 - skal prøve på nytt`() {
stub(WireMock.serverError().withStatus(502).withFault(Fault.CONNECTION_RESET_BY_PEER))
stub(WireMock.serverError().withStatus(502))
post()
wireMockServer.verify(3, RequestPatternBuilder.allRequests())
}
Expand Down Expand Up @@ -89,7 +82,8 @@ internal class RetryOAuth2HttpClientTest {
private fun post(): Exception? {
return try {
client.post(
OAuth2HttpRequest.builder(URI.create(wireMockServer.baseUrl()))
OAuth2HttpRequest.builder()
.tokenEndpointUrl(URI.create(wireMockServer.baseUrl()))
.oAuth2HttpHeaders(OAuth2HttpHeaders.builder().build())
.build(),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ internal class BearerTokenClientCredentialsClientInterceptorTest {

bearerTokenClientInterceptor.intercept(req, ByteArray(0), execution)

verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration.get("1")!!) }
verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["1"]) }
}

@Test
Expand All @@ -45,7 +45,7 @@ internal class BearerTokenClientCredentialsClientInterceptorTest {
assertThat(catchThrowable { bearerTokenClientInterceptor.intercept(req, ByteArray(0), execution) })
.hasMessage(
"could not find oauth2 client config for " +
"uri=http://jwtResource.no and grant type=client_credentials",
"uri=http://jwtResource.no and grant type=OAuth2GrantType[value=client_credentials]",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class BearerTokenClientInterceptorTest {

bearerTokenClientInterceptor.intercept(req, ByteArray(0), execution)

verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["1"]!!) }
verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["1"]) }
}

@Test
Expand All @@ -56,7 +56,7 @@ class BearerTokenClientInterceptorTest {

bearerTokenClientInterceptor.intercept(req, ByteArray(0), execution)

verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["2"]!!) }
verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["2"]) }
}

fun mockBrukerContext(preferredUsername: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal class BearerTokenOnBehalfOfClientInterceptorTest {

bearerTokenClientInterceptor.intercept(req, ByteArray(0), execution)

verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["2"]!!) }
verify { oAuth2AccessTokenService.getAccessToken(clientConfigurationProperties.registration["2"]) }
}

@Test
Expand All @@ -44,7 +44,7 @@ internal class BearerTokenOnBehalfOfClientInterceptorTest {
Assertions.assertThat(Assertions.catchThrowable { bearerTokenClientInterceptor.intercept(req, ByteArray(0), execution) })
.hasMessage(
"could not find oauth2 client config for " +
"uri=http://clientResource.no and grant type=urn:ietf:params:oauth:grant-type:jwt-bearer",
"uri=http://clientResource.no and grant type=OAuth2GrantType[value=urn:ietf:params:oauth:grant-type:jwt-bearer]",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ open class RequestTimeFilter : Filter {
}
}
}

open fun shouldNotFilter(uri: String): Boolean {
return uri.contains("/internal") || uri == "/api/ping"
}
Expand Down
9 changes: 2 additions & 7 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<kotest.version>5.8.0</kotest.version>
<kotlin.version>1.9.22</kotlin.version>
<mockk.version>1.13.9</mockk.version>
<nav.security.token.version>4.1.3</nav.security.token.version>
<nav.security.token.version>3.2.0</nav.security.token.version>

<!--suppress UnresolvedMavenProperty Ligger som secret i github-->
<sonar.projectKey>${SONAR_PROJECTKEY}</sonar.projectKey>
Expand Down Expand Up @@ -54,7 +54,7 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.3</version>
<version>3.2.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down Expand Up @@ -89,11 +89,6 @@
<version>${mockk.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.nimbusds</groupId>
<artifactId>oauth2-oidc-sdk</artifactId>
<version>11.10</version>
</dependency>

<dependency>
<groupId>org.wiremock</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,12 @@ class ClientTokenValidationFilter(

private fun accepted(): Boolean {
try {
val claims = SpringTokenValidationContextHolder().getTokenValidationContext().getClaims(issuerName)
val claims = SpringTokenValidationContextHolder().tokenValidationContext.getClaims(issuerName)

if (claims == null) {
logger.warn("Finner ikke claim=$issuerName")
return false
}

val sub = claims.get("sub") as String?
val oid = claims.get("oid") as String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,7 @@ object EksternBrukerUtils {

fun getBearerTokenForLoggedInUser(): String {
return getFromContext { validationContext, issuer ->
validationContext.getJwtToken(
issuer,
)?.encodedToken ?: throw JwtTokenValidatorException("Klarte ikke hente token fra issuer $issuer")
validationContext.getJwtToken(issuer).tokenAsString
}
}

Expand Down
20 changes: 10 additions & 10 deletions sikkerhet/src/main/java/no/nav/familie/sikkerhet/OIDCUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class OIDCUtil(private val ctxHolder: TokenValidationContextHolder) {
private lateinit var environment: Environment

val subject: String?
get() = claimSet().subject
get() = claimSet()?.subject

fun autentisertBruker(): String {
return subject ?: jwtError("Fant ikke subject")
Expand All @@ -27,36 +27,36 @@ class OIDCUtil(private val ctxHolder: TokenValidationContextHolder) {

fun getClaim(claim: String): String {
return if (erDevProfil()) {
claimSet().get(claim)?.toString() ?: "DEV_$claim"
claimSet()?.get(claim)?.toString() ?: "DEV_$claim"
} else {
claimSet().get(claim)?.toString() ?: jwtError("Fant ikke claim '$claim' i tokenet")
claimSet()?.get(claim)?.toString() ?: jwtError("Fant ikke claim '$claim' i tokenet")
}
}

fun getClaimAsList(claim: String): List<String>? {
return if (erDevProfil()) listOf("group1") else claimSet().getAsList(claim)
return if (erDevProfil()) listOf("group1") else claimSet()?.getAsList(claim)
}

val navIdent: String
get() =
if (erDevProfil()) {
"TEST_Z123"
} else {
claimSet().get("NAVident")?.toString() ?: jwtError("Fant ikke NAVident")
claimSet()?.get("NAVident")?.toString() ?: jwtError("Fant ikke NAVident")
}

val groups: List<String>?
get() =
(claimSet().get("groups") as List<*>?)
(claimSet()?.get("groups") as List<*>?)
?.filterNotNull()
?.map { it.toString() }

fun claimSet(): JwtTokenClaims {
return context().getClaims("azuread")
fun claimSet(): JwtTokenClaims? {
return context()?.getClaims("azuread")
}

private fun context(): TokenValidationContext {
return ctxHolder.getTokenValidationContext()
private fun context(): TokenValidationContext? {
return ctxHolder.tokenValidationContext
}

val expiryDate: Date?
Expand Down
Loading