KeyCloak User validation and getting token

Rohitesh picture Rohitesh · Mar 30, 2018 · Viewed 22.7k times · Source

First of all I am very new to Keycloak and excuse me if something I am asking might be wrong.

I have installed the Keycloak server and I can access the Web UI for the same using:

http://localhost:8008/auth

My requirement is to validate a realm user by passing it to k Keycloak API and to get the token from there in response, and then pass this token for my other Web API calls.

But I was not able to find a simple guide on how I can do this...

UPDATE:


USING UI from KEYCLOAK:

So far now:

  • I am able to create a realm: e.g: DemoRealm

  • Under the Realm I have created the client: e.g: DemoClient

  • Under the client I have created the user: e.g: DemoUser

USING POSTMAN:

I am also able to successfully get the token using

http://localhost:8080/auth/realms/DemoRelam/protocol/openid-connect/token

POST:
{
"grant_type": "client_credentials",
"username": "",
"password": "",
"client_secret":"",
"client_id":"DemoClient"
}

In response I am getting the token.

{
    "access_token": "eyJhbGciOiJSUzI1NiIsINVSHGhepnDu13SwRBL-v-y-04_6e6IJbMzreZwPI-epwdVPQe-ENhpvms2WdGM_DmgMLZ8YQFS4LDl9R7ZHT8AgXe-WCFV6OFkA7zvdeFwQ4kVVZE0HlNgHgoi4DrgMfwwz_ku1yJNJP3ztTY1nEqmA",
    "expires_in": 300,
    "refresh_expires_in": 1800,
    "refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRRnB5YlloMGVEektIdlhOb3JvaFUxdlRvWVdjdP3vbfvk7O0zvppK9N4-oaUqZSr0smHv5LkuLDQYdPuxA",
    "token_type": "bearer",
    "not-before-policy": 0,
    "session_state": "bb1c586a-e880-4b96-ac16-30e42c0f46dc"
}

Furthermore I was diving into more details and found this API guide:

http://www.keycloak.org/docs-api/3.0/rest-api/index.html#_users_resource

In this guide it's mentioned that I can get the users for the realm using Get users Returns a list of users, filtered according to query parameters

GET /admin/realms/{realm}/users

But when I am using POSTMAN to get the users I am getting 403 error code. I am passing the same token as on authentication which I got in the earlier step.

http://localhost:8080/auth/admin/realms/DemoRelam/users

Can anyone please guide me?

Answer

maslick picture maslick · Jun 30, 2019

You have 2 choices: you can act on behalf of some user (as Adnan Khan pointed out), or create a dedicated client for this.

On behalf of the user

1) create a confidential client (I suppose you already got one)

2) create a user and assign an appropriate role/s to it: e.g. view-users from the realm-management group

3) get the token (I'm using curl and jq):

KCHOST=https://yourkeycloak.com
REALM=realm
CLIENT_ID=confidential-client
CLIENT_SECRET=xxxxxxx-yyyyyy-zzzzzzzz
UNAME=user
PASSWORD=passwd

ACCESS_TOKEN=`curl \
  -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" \
  -d "username=$UNAME" -d "password=$PASSWORD" \
  -d "grant_type=password" \
  "$KCHOST/auth/realms/$REALM/protocol/openid-connect/token"  | jq -r '.access_token'`

4) finally call the Admin REST API users endpoint:

curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" $KCHOST/auth/admin/realms/$REALM/users | jq

On behalf of the client (Service account)

1) create a confidential client and make sure to toggle the Service Accounts Enabled setting to On

2) go over to the Service account roles tab and select the appropriate role for this client, e.g. realm-admin from the realm-management group

3) get the access token

KCHOST=https://yourkeycloak.com
REALM=realm
CLIENT_ID=protector-of-the-realm
CLIENT_SECRET=xxxxxxx-yyyyyyyy-zzzzzzzzz

ACCESS_TOKEN=`curl \
  -d "client_id=$CLIENT_ID" -d "client_secret=$CLIENT_SECRET" \
  -d "grant_type=client_credentials" \
  "$KCHOST/auth/realms/$REALM/protocol/openid-connect/token"  | jq -r '.access_token'`

4) call the REST API endpoint:

curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" $KCHOST/auth/admin/realms/$REALM/users | jq

P.S. For debugging I have just written a CLI tool called brauzie that would help you fetch and analyse your JWT tokens (scopes, roles, etc.). It could be used for both public and confidential clients. You could as well use Postman and https://jwt.io

HTH :)