Skip to content

Commit d98e63f

Browse files
committed
feat(introspect): serialize single value audience as string
1 parent 89629b8 commit d98e63f

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

src/main/kotlin/no/nav/security/mock/oauth2/introspect/Introspect.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package no.nav.security.mock.oauth2.introspect
22

3+
import com.fasterxml.jackson.annotation.JsonFormat
34
import com.fasterxml.jackson.annotation.JsonInclude
45
import com.fasterxml.jackson.annotation.JsonProperty
56
import com.nimbusds.jwt.JWTClaimsSet
@@ -90,6 +91,7 @@ data class IntrospectResponse(
9091
@JsonProperty("sub")
9192
val sub: String? = null,
9293
@JsonProperty("aud")
94+
@JsonFormat(with = [JsonFormat.Feature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED])
9395
val aud: List<String>? = null,
9496
@JsonProperty("iss")
9597
val iss: String? = null,

src/test/kotlin/no/nav/security/mock/oauth2/introspect/IntrospectTest.kt

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,52 @@ internal class IntrospectTest {
117117
}
118118
}
119119

120+
@Test
121+
fun `introspect should return single audience as string`() {
122+
val issuerUrl = "http://localhost/default"
123+
val tokenProvider = OAuth2TokenProvider()
124+
val claims =
125+
mapOf(
126+
"iss" to issuerUrl,
127+
"client_id" to "yolo",
128+
"token_type" to "token",
129+
"sub" to "foo",
130+
"aud" to "some-audience",
131+
)
132+
val token = tokenProvider.jwt(claims)
133+
val request = request("$issuerUrl$INTROSPECT", token.serialize())
134+
135+
routes { introspect(tokenProvider) }.invoke(request).asClue {
136+
it.status shouldBe 200
137+
val response = it.parse<Map<String, Any>>()
138+
response shouldContainAll claims
139+
response shouldContain ("active" to true)
140+
}
141+
}
142+
143+
@Test
144+
fun `introspect should return multiple audiences as array of strings`() {
145+
val issuerUrl = "http://localhost/default"
146+
val tokenProvider = OAuth2TokenProvider()
147+
val claims =
148+
mapOf(
149+
"iss" to issuerUrl,
150+
"client_id" to "yolo",
151+
"token_type" to "token",
152+
"sub" to "foo",
153+
"aud" to listOf("audience1", "audience2"),
154+
)
155+
val token = tokenProvider.jwt(claims)
156+
val request = request("$issuerUrl$INTROSPECT", token.serialize())
157+
158+
routes { introspect(tokenProvider) }.invoke(request).asClue {
159+
it.status shouldBe 200
160+
val response = it.parse<Map<String, Any>>()
161+
response shouldContainAll claims
162+
response shouldContain ("active" to true)
163+
}
164+
}
165+
120166
@Test
121167
fun `introspect should return active false when token is missing`() {
122168
val url = "http://localhost/default$INTROSPECT"

0 commit comments

Comments
 (0)