1
1
package no.nav.security.mock.oauth2.grant
2
2
3
+ import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
3
4
import com.nimbusds.jwt.SignedJWT
4
5
import com.nimbusds.oauth2.sdk.ResponseMode
5
6
import com.nimbusds.openid.connect.sdk.AuthenticationRequest
6
7
import io.kotest.assertions.asClue
7
8
import io.kotest.matchers.shouldBe
9
+ import io.kotest.matchers.shouldNotBe
8
10
import no.nav.security.mock.oauth2.http.OAuth2HttpRequest
9
11
import no.nav.security.mock.oauth2.login.Login
10
12
import no.nav.security.mock.oauth2.testutils.authenticationRequest
13
+ import no.nav.security.mock.oauth2.testutils.claims
11
14
import no.nav.security.mock.oauth2.testutils.subject
12
15
import no.nav.security.mock.oauth2.token.DefaultOAuth2TokenCallback
13
16
import no.nav.security.mock.oauth2.token.OAuth2TokenProvider
14
17
import okhttp3.Headers
15
18
import okhttp3.HttpUrl
16
19
import okhttp3.HttpUrl.Companion.toHttpUrl
17
20
import org.junit.jupiter.api.Test
21
+ import org.junit.jupiter.params.ParameterizedTest
22
+ import org.junit.jupiter.params.provider.Arguments
23
+ import org.junit.jupiter.params.provider.MethodSource
24
+ import org.junit.jupiter.params.provider.ValueSource
25
+ import java.util.stream.Stream
18
26
19
27
internal class AuthorizationCodeHandlerTest {
20
28
private val handler = AuthorizationCodeHandler (OAuth2TokenProvider (), RefreshTokenManager ())
@@ -39,16 +47,60 @@ internal class AuthorizationCodeHandlerTest {
39
47
40
48
@Test
41
49
fun `token response with login should return id_token and access_token containing username from login as sub` () {
42
- val code: String = handler.authorizationCodeResponse(
43
- authenticationRequest = " http://authorizationendpoint" .toHttpUrl().authenticationRequest().asNimbusAuthRequest(),
44
- login = Login (" foo" )
45
- ).authorizationCode.value
50
+ val code: String = handler.retrieveAuthorizationCode(Login (" foo" ))
46
51
47
52
handler.tokenResponse(tokenRequest(code = code), " http://myissuer" .toHttpUrl(), DefaultOAuth2TokenCallback ()).asClue {
48
53
SignedJWT .parse(it.idToken).subject shouldBe " foo"
49
54
}
50
55
}
51
56
57
+ @ParameterizedTest
58
+ @MethodSource(" jsonClaimsProvider" )
59
+ fun `token response with login including claims should return access_token containing claims from login` (claims : String , expectedClaimKey : String , expectedClaimValue : String ) {
60
+ val code: String = handler.retrieveAuthorizationCode(Login (" foo" , claims))
61
+
62
+ handler.tokenResponse(tokenRequest(code = code), " http://myissuer" .toHttpUrl(), DefaultOAuth2TokenCallback ()).asClue {
63
+ val claim = SignedJWT .parse(it.idToken).claims[expectedClaimKey]
64
+ claim shouldNotBe null
65
+ jacksonObjectMapper().writeValueAsString(claim) shouldBe expectedClaimValue
66
+ }
67
+ }
68
+
69
+ companion object {
70
+ @JvmStatic
71
+ fun jsonClaimsProvider (): Stream <Arguments > = Stream .of(
72
+ Arguments .of(" { \" acr\" : \" value\" }" , " acr" , " \" value\" " ),
73
+ Arguments .of(" { \" acr\" : { \" reference\" : { \" id\" : \" value\" } } }" , " acr" , " {\" reference\" :{\" id\" :\" value\" }}" )
74
+ )
75
+ }
76
+
77
+ @Test
78
+ fun `token response with login including multiple claims should return access_token containing all claims from login` () {
79
+ val code: String = handler.retrieveAuthorizationCode(Login (" foo" , " { \" acr\" : \" value1\" , \" abc\" : \" value2\" }" ))
80
+
81
+ handler.tokenResponse(tokenRequest(code = code), " http://myissuer" .toHttpUrl(), DefaultOAuth2TokenCallback ()).asClue {
82
+ val claims = SignedJWT .parse(it.idToken).claims
83
+ claims[" acr" ] shouldBe " value1"
84
+ claims[" abc" ] shouldBe " value2"
85
+ }
86
+ }
87
+
88
+ @ParameterizedTest
89
+ @ValueSource(strings = [" {" , " []" , " [\" claim\" ]" , " {}" ])
90
+ fun `token response with login including invalid JSON for claims parsing should return access_token containing no additional claims` (claimsValue : String ) {
91
+ val code: String = handler.retrieveAuthorizationCode(Login (" foo" , claimsValue))
92
+
93
+ handler.tokenResponse(tokenRequest(code = code), " http://myissuer" .toHttpUrl(), DefaultOAuth2TokenCallback ()).asClue {
94
+ SignedJWT .parse(it.idToken).claims.count() shouldBe 10
95
+ }
96
+ }
97
+
98
+ private fun AuthorizationCodeHandler.retrieveAuthorizationCode (login : Login ): String =
99
+ authorizationCodeResponse(
100
+ authenticationRequest = " http://authorizationendpoint" .toHttpUrl().authenticationRequest().asNimbusAuthRequest(),
101
+ login = login
102
+ ).authorizationCode.value
103
+
52
104
private fun HttpUrl.asNimbusAuthRequest (): AuthenticationRequest = AuthenticationRequest .parse(this .toUri())
53
105
54
106
private fun tokenRequest (
0 commit comments