Keycloak: 404 creating a role mapping for a user - keycloak

I'm trying to use Keycloak's admin API in order to add a client-level role to the user role mapping. For this purpose I'm using the admin endpoint :
POST /{realm}/groups/{id}/role-mappings/clients/{client}
e.g.:
http://localhost/tests/admin/realms/testrealm/users/d1a15b4c-9853-4d87-9b8d-d4cf3fac3650/role-mappings/clients/3f222762-5300-48f2-be48-32f001d5a7dc
Request body as:
[
{
"id": "32f02358-9312-4b7b-8584-85dcaf257667",
"name": "test_role_app",
"description": null,
"scopeParamRequired": false
}
]
The id in the body request, is the role ID.
Keycloak is responding with error 404 with message:
{
"error": "Role not found"
}
Not sure what is the problem here as the role exists in the system. What could be wrong here?

Turned out to be that I was using the wrong roleId. I had two roles with same name (one at realm level and another one at client level). After using the correct ID everything worked well!
Additionally the whole request body looks like:
[
{
"id": "94cf6502-0375-4b62-a3ae-465d047738c3",
"name": "test_role_app",
"composite": false,
"clientRole": true,
"containerId": "a7e640cb-751d-4caa-81a0-79d38d31e025"
}
]

Related

Failed to change azure account password from MS Graph Explorer

I am trying to change my password of Azure account from Microsoft Graph Explorer by using this query:
POST https://graph.microsoft.com/v1.0/me/changePassword
{
"currentPassword": "XXX",
"newPassword": "XXX"
}
I got the below error while executing that query:
{ "error": { "code": "Authorization_RequestDenied", "message": "Access
to change password operation is denied.", "innerError": { "date":
"2022-07-10T05:59:39", "request-id":
"1ecc339e-62f4-4703-9e92-181f894b9790", "client-request-id":
"b353d155-13c2-0809-4d83-efb8ae999742" } }
Do I need permission to change my own password? What's the resolution?
I tried to reproduce the same in my environment and got the same error as below:
POST https://graph.microsoft.com/v1.0/me/changePassword
Body
{
"currentPassword": "XXXX",
"newPassword": "XXXX"
}
Please note that, you need Directory.AccessAsUser.All permission consented like below:
After consenting, I am able to change my password successfully like below:
Reference:
user: changePassword - Microsoft Graph v1.0 | Microsoft Docs

clientId missing from resource_access field in jwt token when using impersonation

I'm using Keycloak 14.0.0 and enabled the feature preview of token_exchange in order to do impersonation. After configuring my user in Keycloak to take on the impersonation role on the client "realm-management" (as according to the [documentation][1]), the actual request to do the token exchange fails as the token is not valid.
After some debugging it turns out that the jwt token is indeed malformed:
...
"session_state": "a03aeg0e-b5ce-4a50-9038-c339e50338c4",
"acr": "1",
"allowed-origins": [
"http://0.0.0.0:9180"
],
"scope": "openid identity_provider email admin profile company",
"permissions": [
"consented-readonly",
"readonly",
"trackingdisabled"
],
"resource_access": {
".roles": [
"impersonation"
]
},
"email_verified": false,
"idp": "myidp",
...
In the above, please notice the ".roles". I assume this is incorrect. It should be something like:
"resource_access": {
"myclient": {
"roles": [
"impersonation"
]
}
How can this be fixed?
[1]: https://www.keycloak.org/docs/latest/securing_apps/index.html#impersonation
It turns out that the configuration of a mapper was incorrect. In this case it was the "client roles" mapper (client scopes -> roles -> mapper -> client roles in keycloak ui) which, in my keycloak setup, had the value of:
resource_access..roles
This is incorrect as it should contain a clientId placeholder as shown below:
resource_access.${client_id}.roles
after this change the accessToken includes the actual client resulting in a valid json in the accessToken

Keycloak RestAPI: Assign client role to group

I have trying this:
url="https://{localhost}/auth/admin/realms/{realm_name}/groups/{group_id}/role-mappings"
payload=[{"id":"role_id","name":"Role_name","composite":"false","clientRole":"true","containerId":"client_id"}]
But, it doesnt work, i think it may be related to the wrong payload
Any ideas pls
We can use the python-keycloak lib: https://pypi.org/project/python-keycloak/
there is a function: assign_group_client_roles
The format is correct but you make sure the client has available payloaded role.
This is example for, "Hr" group added "RomoteApp" client the "tile limit" role.
In Keycloak UI, # Client > RemoteApp > Roles
Role name
time limit
Groups > hr
Client Roles: RemoteApp
Available Roles: time limit
Assigned Roles: not yet include "time limit"
POST commend by Postman - I am not yet can attache image due to low level of stan overflow
http://127.0.0.1:8080/auth/admin/realms/Test-realm/groups/9efef6bf-7edb-496e-bc0d-a8d4f5f4e3a9/role-mappings/clients/60a19179-f244-42f8-9950-04f2119a4e5b?client=RemoteApp&id=60a19179-f244-42f8-9950-04f2119a4e5b&realm=Test-realm
in body of postman with row JSON option ( Content-Type : application/json )
[
{
"id": "e17f9f7f-62dc-4998-b058-49b845ff5cef",
"name": "time limit",
"description": "time limit",
"composite": false,
"clientRole": true,
"containerId": "60a19179-f244-42f8-9950-04f2119a4e5b"
}
]
group list
{
"id": "9efef6bf-7edb-496e-bc0d-a8d4f5f4e3a9",
"name": "hr",
"path": "/hr",
"subGroups": []
}
client list
{
"id": "60a19179-f244-42f8-9950-04f2119a4e5b",
"clientId": "RemoteApp",
...
}
also don't remember the access token called by token endpoint w/ grant_type is password
http://127.0.0.1:8080/auth/realms/Test-realm/protocol/openid-connect/token

Not able to create user using keycloak api

Getting token is successful:
Post: http://localhost:8180/auth/realms/public-library/protocol/openid-connect/token
Content type:application/x-www-form-urlencoded
Body:x-www-form-urlencoded
client_id:spring-boot-app
username:pooja.kumawat
password:poojakumawat#23
grant_type:password
Output:Token
Creating a user is getting an error:
Post : http://localhost:8180/auth/public-library/users
Authorization:Bearer+Token
Content type:Application/Json
Body:Raw
{
"username": "name",
"enabled": true,
"emailVerified": false,
"firstName": "first",
"lastName": "last",
"credentials": [
{
"type": "password",
"value": "newPas1*",
"temporary": false
}
]
}
Error is:
{
"error": "RESTEASY003210: Could not find resource for full path: http://localhost:8180/auth/public-library/users"
}
It looks like you are using the wrong endpoint, change it to
http://localhost:8180/auth/admin/realms/public-library/users
And keep in mind, the user who is performing the POST request need to have at least the manage-users realm-management role assigned. Otherwise the response will be 403 Forbidden
What you need to do is go to the realm you are using in keycloak. Then go to the users section and select the user you are you using for the request. Under role Mappings, select realm management and assign this user the role realm admin and manage users role. After that, you will be able to make requests

Login if "Required User Actions" is existing

i have the following problem if an existing keycloak user has one or more required user action.
We use the keycloak (3.4.2.Final) rest api to login into keycloak. But keycloak returns always code 401 (invalid_grant) if user locked out or any required user action exists. So i can not identify what the main problem is.
For lockout i don't need to verify user's password, with any password (calling attackdetection rest api) can i tell the end user that the account is locked BUT for the required user actions not the same, user has to login successfully then can i handle next steps.
For example UPDATE_PASSWORD:
Login with username/password -> Login successfully OR username/password validated -> handle user action -> update password -> user logged in
I would appreciate any ideas.
Just in case someone still cares about an answer:
You can update the User using keycloak's admin REST api.
PUT /auth/admin/realms/myrealm/users/myKeycloakUserId
{
"id": "myKeycloakUserId",
"createdTimestamp": 1547730135139,
"username": "myusername",
"enabled": true,
"totp": false,
"emailVerified": true,
"firstName": "myfirstname",
"lastName": "mylastname",
"email": "myemail",
"attributes": {
"privacyStatementAcceptedDate": [
"2019-01-17T13:02:15.189Z"
],
"welcomeEmailDate": [
"2019-01-17T13:02:30.370Z"
],
"gender": [
"female"
],
"legalAgeConfirmedDate": [
"2019-01-17T13:02:15.189Z"
],
"termsAcceptedDate": [
"2019-01-17T13:02:15.189Z"
]
},
"disableableCredentialTypes": [
"password"
],
"requiredActions": [],
"notBefore": 0,
"access": {
"manageGroupMembership": true,
"view": true,
"mapRoles": true,
"impersonate": true,
"manage": true
}
}
Someone might want to try to send only the requiredActions-property instead of all other values (since these should be retrieved first), but I don't know if this would actually work. I thought: Better safe than sorry, so I retrieve the data first and then I only set the requiredActions-property to an empty array and send it back.
If you are using the Java client library (keycloak-admin-client), you might do it like this:
org.keycloak.admin.client.Keycloak keycloak = KeycloakBuilder.builder()
.serverUrl(KEYCLOAK_ADMIN_BASEURL))
.realm(KEYCLOAK_ADMIN_REALM))
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.clientId(KEYCLOAK_ADMIN_CLIENTID))
.clientSecret(KEYCLOAK_ADMIN_CLIENTSECRET))
.build();
final UserResource keycloakUserResource = keycloak.realm(
configurationService.getValue(KEYCLOAK_ADMIN_REALM)).users().get(
keycloakUserId);
//load the users user-representation from Keycloak
final UserRepresentation userRepresentation = keycloakUserResource.toRepresentation();
if (userRepresentation == null) {
throw new Exception("Failed to load the UserRepresentation for the current User");
}
//adapt the user-representation
userRepresentation.setRequiredActions(Collections.emptyList());
//update user in Keycloak
keycloakUserResource.update(userRepresentation);