Closed SrMouraSilva closed 3 years ago
In 2.3.0, I reorganized the properties, but this is mostly code shuffling, you should have about the same configuration options.
It is possible I lost a few very low-level JWT claims like jti
in the process, but see at the end of this post how you can set it in privateClaims
).
How comes your @Controller code (or @Service or any other "business" code) needs access to such claims (session_state
and jti
)? Shouldn't this be used by upstream frameworks only (like Spring-security, before access is granted and KeycloakAuthenticationToken is build)?
The reason for this change is I chose to get closer to the OpenID spec to re-use some code I wrote for another OpenID Authentication
implementation (I personally don't use KeycloakAuthenticationToken
any more mostly because Keycloak Spring libs are moving too slow). This spec is there https://openid.net/specs/openid-connect-core-1_0.html
Current state:
@WithMockKeycloakAuth(id = @IdTokenClaims(...))
@WithMockKeycloakAuth(accessToken = @KeycloakAccessToken(...))
What this means for you:
id
or oidc
properties (sub
is standard IDToken claim and so under id
)accessToken
propertyjti
and session_state
or claims I missed), you should still be able to set it in privateClaims
As usual, samples are rather informative:
@Test
@WithMockKeycloakAuth(
authorities = { "USER", "AUTHORIZED_PERSONNEL" },
id = @IdTokenClaims(sub = "42"),
oidc = @OidcStandardClaims(
email = "ch4mp@c4-soft.com",
emailVerified = true,
nickName = "Tonton-Pirate",
preferredUsername = "ch4mpy"),
accessToken = @KeycloakAccessToken(
realmAccess = @KeycloakAccess(roles = { "TESTER" }),
authorization = @KeycloakAuthorization(
permissions = @KeycloakPermission(rsid = "toto", rsname = "truc", scopes = "abracadabra"))),
privateClaims = @ClaimSet(stringClaims = @StringClaim(name = "foo", value = "bar")))
public void whenAuthenticatedWithKeycloakAuthenticationTokenThenCanGreet() throws Exception {
api.get("/greet")
.andExpect(status().isOk())
.andExpect(content().string(startsWith("Hello ch4mpy! You are granted with ")))
.andExpect(content().string(containsString("AUTHORIZED_PERSONNEL")))
.andExpect(content().string(containsString("USER")))
.andExpect(content().string(containsString("TESTER")));
}
Hi, thanks for the response!
How comes your @controller code (or @service or any other "business" code) needs access to such claims (session_state and jti)? Shouldn't this be used by upstream frameworks only (like Spring-security, before access is granted and KeycloakAuthenticationToken is build)?
I create a audit Filter what use this information by auditing purposes. In fact this fields are not relevant by the test, but the object is used to other things, including a way to obtained the user data. As this three fields are always informed by Keycloak, I defined they as not null
in my Kotlin code
It is possible I lost a few very low-level JWT claims like jti in the process, [...]
I don't found any reference in the current branch to jti
by the Github seach
--
Ok, now I change to the similar example,
@WithMockKeycloakAuth(
authorities=[CLASSROOM_TURMAS_CADASTRAR_COMANDO],
id=IdTokenClaims(sub="00000000-0000-0000-0000-000000000000"),
oidc = OidcStandardClaims(),
privateClaims = ClaimSet(stringClaims=[
StringClaim(name = "jti", value = "00000000-0000-0000-0000-000000000000"),
StringClaim(name = IDToken.SESSION_STATE, value = "00000000-0000-0000-0000-000000000000")
])
)
but this privateClaims only populate otherClaims
This spec is there https://openid.net/specs/openid-connect-core-1_0.html
session_scope
can be found in https://openid.net/specs/openid-connect-session-1_0.html#CreatingUpdatingSessions, but is a draft
Congratulations for the awesome project :D !
I re-open. Further investigations needed
Renamed privateClaims
to otherClaims
in @WithMockKeycloakAuth
for clarity: Keycloak's token model does not support private claims at root as per JWT spec. Instead, it maps unknown claims to otherClaims
properties.
Added jti
and nbf
(from JWT spec) to @IdTokenClaims
(an ID token is a JWT)
Also added session_state
to @IdTokenClaims
as per https://openid.net/specs/openid-connect-session-1_0.html#CreatingUpdatingSessions
Sample usage:
@WithMockKeycloakAuth(
authorities = { "USER", "AUTHORIZED_PERSONNEL" },
id = @IdTokenClaims(
sub = "42",
jti = "123-456-789",
nbf = "2020-11-18T20:38:00Z",
sessionState = "987-654-321"),
oidc = @OidcStandardClaims(
email = "ch4mp@c4-soft.com",
emailVerified = true,
nickName = "Tonton-Pirate",
preferredUsername = "ch4mpy"),
accessToken = @KeycloakAccessToken(
realmAccess = @KeycloakAccess(roles = { "TESTER" }),
authorization = @KeycloakAuthorization(
permissions = @KeycloakPermission(rsid = "toto", rsname = "truc", scopes = "abracadabra"))),
otherClaims = @ClaimSet(stringClaims = @StringClaim(name = "foo", value = "bar")))
Please re-open if you find other missing claims.
P.S. @SrMouraSilva sorry for abnormally long processing. I got caught by urgent stuff at work, then changed my laptop (and had to re-install everything) and then just ... forgot about this opened issue => so very, very sorry :(
@SrMouraSilva sorry for abnormally long processing. I got caught by urgent stuff at work, then changed my laptop (and had to re-install everything) and then just ... forgot about this opened issue => so very, very sorry :(
Hi ch4mpy! I completely understand the situation. Thank you for your availability! I am updating my code.
In the version 2.1.0, is possible to define sessionState
But in the version 2.4.0, I don't found a way to define
AccessToken.sessionState
(session_state
). Also, I need define tooAccessToken.id
(jti
) andAccessToken.subject
(sub
).I found how to define the
sub
, but not othersMaybe a way to do this is defining a hashmap or something like to add all the (custom) token values that are needed