Generate Keycloak Offline Token - keycloak

I am new to Keycloak identity and user management.
I am primarily looking for a method to generate offline token.
Currently I have
Authorization URL, Access Token Request & Refresh Token Request
In order to generate offline tokens we need to add additional parameter as scope=offline_access
I am not sure why in my case it is not getting generated as I have validated the bearer token from jwt.io the "typ" is not "offline".
The access token request is
curl \
-d "client_id=<my-client-id>" -d "client_secret=<client-secret>" \
-d "username=<user>" -d "password=<pass>" \
-d "grant_type=password" \
-d "scope=openid info offline_access" \
https://localhost:8080/auth/realms/demo/protocol/openid-connect/token | jq
Method: POST
URL: https://keycloak.example.com/auth/realms/myrealm/protocol/openid-connect/token
Body type: x-www-form-urlencoded
Form fields:
client_id : <my-client-name>
grant_type : refresh_token
refresh_token: <my-refresh-token>
Please suggest

Related

How to add realm-admin to an User using keycloak rest-api

When I add a role to an user, I search that client-role by name and then I get this role representation and add to the user. But I couldn't find out how to search the "realm-admin" role and how to add that to the user with rest api.
That's the url I'm using to search my client-role (GET):
https://{my-keycloak-url}/auth/admin/realms/{realm-name}/clients/{id}/roles/{role-name}
And that's the url I'm using to add this role to the user (PUT):
https://{my-keycloak-url}/auth/admin/realms/{realm-name}/users/{user-id}/role-mappings/clients/{client-id}
What's the equivalent to this "realm-admin"?
You can assign the realm-admin role to user by this API
POST https://{my-keycloak-url}/auth/admin/realms/{realm-name}/users/{user-id}/role-mappings/clients/{realm-management-id}
with this body payload
[
{
"id":{realm-admin-id},
"name":"realm-admin",
"description":"${role_realm-admin}",
"composite":true,
"clientRole":true,
"containerId":{realm-management-id}
}
]
Get master token
This is demo by Postman
OR curl command
curl --location --request POST 'http://localhost:8180/auth/admin/realms/my-realm/users/1b058869-a65d-4648-b4e2-4f5bf7430ea6/role-mappings/clients/33f00bff-d735-4402-88bc-51ea055d15c1' \
--header 'Authorization: Bearer $token' \
--header 'Content-Type: application/json' \
--data-raw '[
{
"id":"c8a60657-9545-4ab3-9913-0186fdb93213",
"name":"realm-admin",
"description":"${role_realm-admin}",
"composite":true,
"clientRole":true,
"containerId":"33f00bff-d735-4402-88bc-51ea055d15c1"
}
]'
GET {user-id} by user list API
GET {realm-management-id} by client list API
GET {realm-admin-id} by client role list API

Keycloak: All API response with 404

I followed this tutorial to setup Keycloak and create user but the response for the step of Generating Access Tokens With Keycloak's API 404. I'm using Keycloak version 18.0.0
In the logs of keycloak I found this error
2022-06-12 23:59:57,177 DEBUG [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-3) Error response 404: javax.ws.rs.NotFoundException: RESTEASY003210: Could not find resource for full path: http://localhost:8080/auth/realms/test/protocol/openid-connect/token
From keycloak 17+ there are changes in resource or token URIs. Try removing auth from your request URL.
If you are using Keycloak version < 17
curl -k -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=your-client" -d "username=some-user" -d "password=hardpassword" -d "grant_type=password" -X POST http://localhost:8080/auth/realms/yourrealm/protocol/openid-connect/token
If you are using Keycloak version > 17
curl -k -H "Content-Type: application/x-www-form-urlencoded" -d "client_id=your-client" -d "username=some-user" -d "password=hardpassword" -d "grant_type=password" -X POST http://localhost:8080/realms/yourrealm/protocol/openid-connect/token
You did set in Headers instead of Body.
Move the Key & Values to Body.
You can verify Token URL by click "OpenID Endpoint Configuration" link
It will show Token URL

Keycloak API to create users returns a 403 Forbidden

Experimenting with Keycloak as an Identity Provider. I'm running it by using the ./standalone.sh script.
So, I obtain the access_token like this:
curl --request POST \
--url http://localhost:8080/auth/realms/master/protocol/openid-connect/token \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data grant_type=client_credentials \
--data client_id=admin-cli \
--data client_secret=<the-client-secret-under-master-realm-for-admin-cli-client>
Response:
{
"access_token": "the-access-token",
"expires_in": 60,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "profile email"
}
And then quickly, under my test-realm I try to create a user as follows:
curl --request POST \
--url http://localhost:8080/auth/admin/realms/test-realm/users \
--header 'Authorization: Bearer the-access-token' \
--header 'Content-Type: application/json' \
--data '{
"firstName": "Sergey",
"lastName": "Kargopolov",
"email": "test#test.com",
"enabled": "true",
"username": "app-user"
}'
And I get hit with a 403:
< HTTP/1.1 403 Forbidden
< X-XSS-Protection: 1; mode=block
< X-Frame-Options: SAMEORIGIN
< Referrer-Policy: no-referrer
< Date: Thu, 28 Jan 2021 23:43:57 GMT
< Connection: keep-alive
< Strict-Transport-Security: max-age=31536000; includeSubDomains
< X-Content-Type-Options: nosniff
< Content-Type: application/json
< Content-Length: 25
Is there something I'm missing? I'm following this tutorial and I'm doing everything exactly as described!
Edit: I tried the Password Grant way to obtain the Bearer Token and that worked, but NOT the client secret way. I obviously prefer the client secret way (which is where I'm stuck currently). What could be the issue here?
To create the user using the Keycloak Rest API, one just need to request from the admin-cli client a token on behalf of the admin user by providing its name and password, for instance as follows:
TOKEN=$(curl -k -sS -d "client_id=admin-cli" \
-d "username=$ADMIN_NAME" \
-d "password=$ADMIN_PASSWORD" \
-d "grant_type=password" \
http://$KEYCLOAK_IP/auth/realms/master/protocol/openid-connect/token)
from the $TOKEN object extract the access token (let us named $ACCESS_TOKEN).
And then create the user as follows:
curl -k -sS -X POST https://$KEYCLOAK_IP/auth/admin/realms/$REALM_NAME/users \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "$USER_JSON_DATA"
$USER_JSON_DATA will be the json data representation of the user to be created. There is no need to add the role admin to the master admin deployed with Keycloak by default.
If setup normally, you would just need to know (as I already described) the admin's name and password, which is configured in the initial setup anyway.
If you click on the admin user > roles, you would see the following:
The admin user, has already the admin role.
Edit: I tried the Password Grant way to obtain the Bearer Token and
that worked, but NOT the client secret way. I obviously prefer the
client secret way (which is where I'm stuck currently). What could be
the issue here?
Now if you change the admin_cli configuration exactly as you did then you need to add to the Service-account-admin-cli user the role admin.
Now the problem is that Service-account-admin-cli user is hidden in the User section. Nonetheless, you can do the following:
Request again the admin token with your setup;
Go to Master Realm > Clients > admin-cli > Session > Click on [Show Session]:
click on the user service-account-admin-cli;
Go to Role Mappings;
Assign the admin role;
Since the service-account-admin-cli user has now the admin role, a token request on that user's behalf will contain the necessary privileges to create the users.
If the aforementioned does not work, then do the following go to:
Realm Master;
Clients > admin-cli;
Go to Mappers;
Click on [Create];
As Mapper Type select "Hardcoded Role";
Click on Select Role and selection "admin";
Click [Save].

Keycloak cannot verify user information with a valid token

I'm setting up Keycloak as an authentication server https://github.com/keycloak/keycloak/releases/download/12.0.0/keycloak-12.0.0.zip
Java 11
Documentation: https://github.com/keycloak/keycloak-documentation/blob/master/securing_apps/topics/oidc/oidc-generic.adoc
I can generate the access_token via /realms/{realm-name}/protocol/openid-connect/token
but I cannot call the userinfo endpoint /realms/{realm-name}/protocol/openid-connect/userinfo using a valid access_token which I get from the first API.
POST http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/token
{
client_secret: ...,
grant_type: ...,
client_id: ...,
}
response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICIxOE..."
"expires_in": 3600,
"refresh_expires_in": 0,
"token_type": "Bearer",
"not-before-policy": 0,
"scope": "create"
}
But here is the result when I call the get user info API
GET http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/userinfo
Header: Bearer ${access_token}
Are there any suggestions?
Thank you
Post man test
Keycloak server's log is same
Keycloak bug
I think this is an issue on KC 12.0
When I use KC 11.0.3, above APIs work fine
https://github.com/keycloak/keycloak-community/issues/224
The Jira story:
https://issues.redhat.com/browse/KEYCLOAK-17217
Make sure you are calling the endpoint as follows.
First getting the token:
curl -d "client_id=$YOUR_CLIENT_ID" \
-d "client_secret=$YOUR_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/token)
Extract from the JSON response the access_token field (e.g., jq -r .access_token)
Then call the userinfo as follows:
curl -X GET http://127.0.0.1:8080/auth/realms/test/protocol/openid-connect/userinfo \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN"
With Postman:
For a setup with Realm Name = "test", client_id = "test", client_secret = "63b61af0-5a99-41d7-8f9b-4e3059b8b9ab" and using client_credentials grant_type.
Getting the token:
and getting the userinfo:
EDIT
The approach below works with Keycloak 10.0.x, and 11.0.x, but gets exactly the same issues as OP's for the version Keycloak 12.0.x (including the latest release Keycloak 12.0.2).
This seams to be regression added with Keycloak 12.0.0 follow this issue for update information.

How do I create a JWT Token for Prime Trust's API?

I am working with Prime Trust's API and I'm unable to create a JWT token. I am following the documentation which states the following:
Getting Started with the Custody APIs - (Sandbox Specific)
You need totake the current steps to get started via the APIs
Create a new User
Authenticate with the APIs by getting a JWT.
Create an Account.
Test Mode APIs - Approve the owner of the account for CIP and AML.
Test Mode APIs - Open an Account for Funds
I was able to create a user following the documentation, but I'm stuck on the creation of the JWT Token. According to the documentation I should create the token using the below:
JSON Web Tokens (JWTs)
JSON Web Tokens or JWTs are the preferred method of authentication for all requests besides actually generating a JWT. Since JWTs are not persisted server resources, they are not created using a JSONAPI style request or response.
Creating a new JWT
A new JWT can be created by passing a user's credentials using HTTP
Basic Authorization to the following endpoint. Any special settings on
the JWT such as IP whitelisting, expiration time or TOTP MFA must be
passed in as form values during creation.
POST /auth/jwts
Here's the example call they give:
curl --location --request POST "https://sandbox.primetrust.com/auth/jwts" \
--header "Content-Type: application/x-www-form-urlencoded" \
--form "expires_at=2019-06-06T07:30:40Z" \
--form "otp=382948" \
--form "cidr[]=192.168.1.213/32" \
--form "cidr[]=127.0.0.1/32"
I've tried a combination of different calls with the details outlined below, but have the below error on all of my attempts:
401 Unauthorized
{
"errors": [
{
"status": 401,
"title": "Not authenticated."
}
]
}
Bodies
POST https://sandbox.primetrust.com/auth/jwts
POST https://sandbox.primetrust.com/auth/jwts
{
"email": "email#email.com",
"password": "123abc"
}
POST https://sandbox.primetrust.com/auth/jwts
{
"data": {
"email": "email#email.com",
"password": "123abc"
}
}
POST https://sandbox.primetrust.com/auth/jwts
{
"name": "name",
"email": "email#email.com",
"password": "123abc"
}
POST https://sandbox.primetrust.com/auth/jwts
{
"id": {guid},
"name": "name",
"email": "email#email.com",
"password": "123abc"
}
POST https://sandbox.primetrust.com/auth/jwts
{
"id": {guid},
"password": "123abc"
}
Headers
Content-Type: application/json
expires_at: 2019-12-31T11:59:59Z
alg: HS256
typ: JWT
I recognize that my calls don't line up with the example call exactly, but my understanding from the documentation is that all that should be required is a name & password to generate the JWT token. What am I missing?
Update 1
Based on reaching out to Prime Trust support the username/email need to be included as parameters rather than in the body of the url. I tried the below URLs without success
https://sandbox.primetrust.com/auth/jwts?email=email#email.com&password=123abc&id={guid}
https://sandbox.primetrust.com/auth/jwts?email=email#email.com&password=123abc
https://sandbox.primetrust.com/auth/jwts?password=123abc&id={guid}
https://sandbox.primetrust.com/auth/jwts?name=name&password=123abc
According to docs:
Creating a new JWT
A new JWT can be created by passing a user's credentials using HTTP Basic Authorization to the following endpoint. Any special settings on the JWT such as IP whitelisting, expiration time or TOTP MFA must be passed in as form values during creation.
So basically all you need is create an Authorization header set to Basic Auth with your credentials:
curl -X POST \
https://sandbox.primetrust.com/auth/jwts \
-H 'Authorization: Basic YOUR_BASE64_ENCODED_EMAIL_AND_PASSWORD' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'cache-control: no-cache'