Keycloak RestAPI: Assign client role to group - keycloak

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

Related

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: 404 creating a role mapping for a user

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"
}
]

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

Api created with Chalice and a Cognito authorizer returns “Unauthorized”

I'm trying to integrate Cognito using the built-in login dialog with AWS Chalice. This is what I tried:
# This passes in correct arn for my pool, not xxxx
authorizer = CognitoUserPoolAuthorizer(
'end_users_dev', provider_arns=['arn:aws:cognito-idp:us-west-2:xxxx])
#app.route('/test', cors=True, authorizer=authorizer)
def test():
return {"result": "Success with authorizer"}
#app.route('/test2', cors=True)
def test2():
return {"result": "Success without authorizer"}
The second method (test2) works but the first method (test) returns (as expected):
{
"message": "Unauthorized"
}
Now I attempt to make the test with authorization work by passing in a header:
Authorization: <the token I get passed in from the
built in login page callback as "id_token">
I can verify the JWT token contents and signature manually and that the user pool is showing up in API Gateway as "Authorization" for the test resource, but I'm still getting the same "Unauthorized" message. What am I missing?
(Note: I also posted this at https://forums.aws.amazon.com/message.jspa?messageID=871715#871715 but haven't received any response in 2 days)
I would check to make sure your IAM policy chalice is running allows access to cognito.
You can add these as needed from the AmazonCognitoPowerUser policy to your policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*",
"cognito-idp:*",
"cognito-sync:*",
"iam:ListRoles",
"iam:ListOpenIdConnectProviders",
"sns:ListPlatformApplications"
],
"Resource": "*"
}
]
}
As see at the link below "
Whenever your application is deployed using chalice, the auto generated policy is written to disk at /.chalice/policy.json. When you run the chalice deploy command, you can also specify the --no-autogen-policy option. Doing so will result in the chalice CLI loading the /.chalice/policy.json file and using that file as the policy for the IAM role. You can manually edit this file and specify --no-autogen-policy if you'd like to have full control over what IAM policy to associate with the IAM role.
"
As seen under the policy section here: https://github.com/aws/chalice
$ chalice gen-policy
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListAllMyBuckets"
],
"Resource": [
"*"
],
"Effect": "Allow",
"Sid": "9155de6ad1d74e4c8b1448255770e60c"
}
]
}

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);