Reputation: 1148
what I am trying to do:
I have an app that takes in login credentials: username and password for a user. I have a rest api that internally calls the keycloak REST API: /auth/realms/realmname/protocol/openid-connect/token and gets the access token for this user.
Now I am building another REST API to access a resource where I want to do the following: doSomething(accesstoken, data)
{
a) call keycloak API to validate access token and get roles.
b) if role == manager, process(data)
c) else: return error msg.
}
Now, how do I do (a): validating the access token and getting the roles associated with it. I know we can do: auth/realms/realmname/protocol/openid-connect/userinfo but that only gives the details about the user like name, email, etc. but does not display any roles. Here's an example I got:
{
"name": "test user",
"sub": "e2bad34d-a1a9-4d70-ac84-bd3a3246023e",
"email_verified": false,
"preferred_username": "user",
"given_name": "test",
"family_name": "user"
}
As seen, it doesnt give the roles at all. How do I then tell what roles this access token has? Interestingly, when I search for this, many resources are suggesting the above userinfo endpoint. But this merely tells me taht the access token I provided is valid. Does not give roles for that. In other words - it authenticates but does not authorize.
Please suggest.
Thanks, Anand
Upvotes: 20
Views: 69159
Reputation: 1326
In the new Keycloak interface, including the realm roles in the token is a bit easier and does not require adding any custom mappers.
You can can enable this by going to Client scopes
-> roles
-> Mappers
-> realm roles
. Then just toggle Add to userinfo
and save.
Upvotes: 9
Reputation: 9961
Follow the below steps:
Step 1: Hit the below curl to get the access_token:
curl --location 'http://localhost:18080/auth/realms/test-realm/protocol/openid-connect/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCIgO...' \
--header 'Cookie: OPERATE-SESSION=DD9F694EE1D511CAE6E126E5503A8995; TASKLIST-SESSION=A0841A5A17C43122443A3DAC4A88060A' \
--data-urlencode 'client_id=test-realm' \
--data-urlencode 'client_secret=8lu1gy4v0Ajt5WjyjgiTXKzuLijE8lpe' \
--data-urlencode 'grant_type=client_credentials'
Step 2: You will get the access_token in response:
{
"access_token": "eyJhbGciOiJSUzI1...I9X3Exs5a_jR_gjmHO6yLZBuoiS3G2BU8_i9Bb2DYDCWWz5awbsg",
"expires_in": 36000,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile email"
}
Step 3: Now get the user data with the above access token by using below curl:
curl --location 'http://localhost:18080/auth/admin/realms/test-realm' \
--header 'Authorization: bearer eyJhbGciOiJSUzI1NiIsInR5cCI...Sa3upI9X3Exs5a_jR_gjmHO6yLZBuoiS3G2BU8_i9Bb2DYDCWWz5awbsg' \
--header 'Cookie: OPERATE-SESSION=DD9F694EE1D511CAE6E126E5503A8995; TASKLIST-SESSION=A0841A5A17C43122443A3DAC4A88060A'
Response:
{
"id": "test-realm",
"realm": "test-realm",
"displayName": "test-realm",
"displayNameHtml": "test-realm",
"failureFactor": 30,
"browserFlow": "browser",
"registrationFlow": "registration",
"defaultRole": {
"id": "f2c105fc-2a47-4fba-93d2-c8d31f9b2977",
"name": "default-roles-test-realm",
"description": "${role_default-roles}",
"composite": true,
"clientRole": false,
"containerId": "test-realm"
}
.
.
}
Upvotes: 0
Reputation: 71
After adding role in the roles section , need to move available roles into the Assigned Roles of the scope tab of the respective client section.
Upvotes: 1
Reputation: 11164
Additionally, if the full scope is not allowed then you need to add the relevant roles to the scope, so they can appear in the token.
Upvotes: 6
Reputation: 740
In Keycloak admin Console, you can configure Mappers under your client. Add a builtin Mapper of type "User Realm Role", then open its configuration e.g. change Token Claim Name if you want.
Client roles can be configured similarly, but they are returned by default in the token under the name resource_access.${client_id}.roles
The the client side you can parse the token to find the roles. E.g. In an angular application and using the keycloak-angular adapter, you can have a the token as a json object by calling keycloak.getKeycloakInstance().tokenParsed.
In a spring boot application and using the Keycloak java api, you can find the roles under the field "otherClaim" in the following class https://www.keycloak.org/docs-api/10.0/javadocs/org/keycloak/representations/AccessTokenResponse.html
In both representations you will find the roles under the "Token Claim Name" defined in the client mapper configuration
Upvotes: 19