'Accessing keycloak roles / users attributes from Java API
I've created a role and and a user in Keycloak and added one attribute in both of them; for example:
my_role_attr = 'x'
my_user_attr = 'y'
Then I'm trying to access that info. via the JAVA KeycloakSecurityContext (and the associated AccessToken / IDToken). I can see the name of the roles and the user information but I cannot find those attributes.
I understand that I've to creat a Protocol Mapper "User Attribute" to map the "my_user_attr" into a Token Claim. Then it's fine I can get the value in the AccessToken / IDToken.
But I cannot find a way to get the role attribute. I do not see any "Protocol Mapper" for role attribute. Am I missing something.
Solution 1:[1]
I have been trying to do the same thing; and it is not easy, however you can use the script mapper with some success. The source code at https://github.com/keycloak/keycloak/blob/master/server-spi/src/main/java/org/keycloak/models/RoleModel.java has some useful information. This SO item (thank you Andre B) also has useful information How to create a Script Mapper in Keycloak?.
My (not perfect or complete) solution is:
/**
* Available variables:
* user - the current user
* realm - the current realm
* token - the current token
* userSession - the current userSession
* keycloakSession - the current userSession
*/
var roles = [];
var client = keycloakSession.getContext().getClient();
user.getClientRoleMappings(client).forEach(function(roleModel) {
var attr = [];
var names = {};
var rn = roleModel.getName();
var map = roleModel.getAttributes();
map.forEach(function(key, value){
var k = {};
var a = false;
value.forEach(function(l){
a = (l === 'true');
});
k[key] = a;
attr.push(k);
});
names[rn] = attr;
roles.push(names);
});
exports = roles;
Note that you probably need to set 'Multivalued' to "ON" and the 'Claim JSON Type' to "Select One..".
Solution 2:[2]
A more generic answer should be
var roles = [];
var client = keycloakSession.getContext().getClient();
user.getRoleMappings().forEach(function(roleModel) {
var attr = {};
var names = {};
var rn = roleModel.getName();
var map = roleModel.getAttributes();
map.forEach(function(key, value){
attr[key] = value;
});
roles[rn] = attr;
});
exports = roles;
to export roles' attributes like
"Role1": {
"key1": [
"Values1"
],
"key2": [
"values2"
]
}
Solution 3:[3]
No, you are not missing something. It is just not implemented. However, there is a feature request. You may want to watch and vote up KEYCLOAK-17418.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Peter |
Solution 2 | mikiqex |
Solution 3 | mikiqex |