Impersonation – Attribute to Denote it’s Impersonation of Token - keycloak

We have impersonation roles for a number of admins -- it's working as expected.
A Client application, for audit purposes, would like to be informed when a token issued is via impersonation -- is there a way we can send an attribute/claim to the Client informing that the token is an Admin impersonating a user?

Yes, Keycloak stores that information in user session notes. The information can be mapped via builtin mappers.
Follow these steps:
Navigate to Clients -> <your client> -> Mappers
Click Add Builtin
Choose Impersonator Username and/or Impersonator User ID (depends on whether you want the username or id as a claim in the token)
Click Add selected
That's it. Your tokens contain the information as shown below:
{
...
"sub": "9ab9bfd1-f95d-4aa1-a8b2-0d1fb06b365a",
"preferred_username": "test",
...
"impersonator": {
"id": "2d2f4b4a-716c-4428-97cd-22fa731c0d9a",
"username": "admin"
}
...
}

Related

KeyCloak POST user with federationLink

I'm trying to make a POST request to our KeyCloak.
I can create a user with no problem but once i provide the post request with the federationLink this isn't picked up. I tried it both with the ID and the string of the Federation Link. I noticed that the added Attributed aren't picked up aswell.
The body i post is:
"username": "xx#local",
"email": "xx#local",
"emailVerified": true,
"enabled": true,
"federationLink": "qa.exn-dir.xxx.com/cn=xxx,cn=xxxx,o=xxx",
"attributes":{
"PHONE_NUMBER": [
"xxxx"
],
"CARD_NUMBER":[
"xxx"
]
},
"credentials": [
{
"type": "password",
"value": "12345"
}
]
And i post this to /auth/admin/realms/REALM/users
When looking at the created user this is still in the default federation and not the one we provided in the body.
Any idea how i could solve this?
User federation in keycloak provide functionality to import user data from your selected LDAP system, source from keycloak documentation
Keycloak can store and manage users. Often, companies already have LDAP or Active Directory services that store user and credential information. You can point Keycloak to validate credentials from those external stores and pull in identity information.
That means keycloak does not store the user credential, keycloak only point to those external stores to validate the user credentials.
Quoting from your comment replying to #sventorben
Thanks for the reply. The users that we need to create in case are external users and they need to be added in keycloak using the API. Atleast that is what i'm told.. But they need to be added to a specific federationLink. This is my first time using KeyCloak so i'm still new to the whole thing
In case of your requirement to create external users:
You can create it and store the user data information and credential in keycloak, that means you need to send the appropriate user data and credentials along to the keycloak so that keycloak can use it.
Or if you prefer to load the users data and validate the credential from your LDAP system, then first you need to register the external users to your LDAP system just like #sventorben said, and then let keycloak automatically synchronize these new users (based on your synchronize settings of the user federation) or if you prefer manually, you can do it via keycloak admin console.

keycloak - give users different permissions per tenant / account

We are using Keycloak for a SaaS offering. Each user is part of a tenant / account and has specific roles for accessing this account's data. The roles are configured in Keycloak and the related account is saved as a user attribute on the user.
Now we've got a new requirement to give users access to multiple accounts. And for each of these accounts the user might have different roles:
User A:
- Account A:
- ADMIN
- Account B:
- Reader
User B
- Account B:
- Reader
...
I found a lot of articles about different approaches to multi tenancy, but nothing in this direction. Most of the articles combined roles and groups. But in my case I would need to create a new group for every account. So I would end up with thousands or millions of groups.
Right now my APIs can authorize requests based on the issued JWT. Ideally I can keep this.
What's the best way to get this structure (users having access to multiple accounts with different roles) into place?
Is this actually possible with keycloak?
Or am I thinking into the wrong direction?
It sounds like a rather common use case.
Thanks a lot already.
The roles are configured in Keycloak and the related account is saved as > a user attribute on the user.
I am not sure why you need this, since you can extrapolate that based on the user role.
Now we've got a new requirement to give users access to multiple
accounts. And for each of these accounts the user might have different
roles:
If I fully understood your problem I think it can be solved with Client Level roles. For instance:
Go to :
Your Realm;
Clients;
Account A;
Roles;
Add Role;
Set the role and save it
To set the role to the user go to
Your Realm;
Users;
Click on the user;
Role Mapping;
From the Client Roles dropdown select the client (e.g., Account A)
Add the Role;
Right now my APIs can authorize requests based on the issued JWT.
Ideally I can keep this.
How a token request to the Account A on behalf of user a would look like:
"acr": "1",
"realm_access": {
"roles": [
"offline_access",
"uma_authorization"
]
},
"resource_access": {
"AccountA": {
"roles": [
"ADMIN"
]
},
"AccountB": {
"roles": [
"Reader"
]
},
"account": {
"roles": [
"manage-account",
"view-profile"
]
}
},
One might say that when requesting a token from client Account A one does not really care about the roles in the client Account B. That can be solved by using Keycloak's Scope Feature. With this feature one can select the roles from other clients that are relevant to the current client. By default, all roles are included. Nonetheless, to filter the roles one needs to go:
Your Realm;
Clients;
Client Account A in this case;
Scope;
Switch to OFF the option Full Scope Allowed;
Save.
How the token looks like now:
"resource_access": {
"AccountA": {
"roles": [
"ADMIN"
]
}
},

Options for creating a Grafana API Token

My organization runs a grafana 7.0 instance that only allows SSO logins. I would like to create an API token for my user account but based on these instruction it seems like doing so is not possible without supplying a password. Is this understanding accurate?
As #Amal.Touzani mentioned, API key is created per organisation, not per user.
Instruction, mentioned by you, needs admin password to authenticate the admin user during API token creation. Later on access level will be defined by role specified in request, in example it is "role": "Admin". Role could be Viewer, Editor or Admin (as mentioned here)
Of course, all these steps could be done from Grafana Administration UI:
I think your user should have the permission to create API token but you don't supply the
password.
Based on the documentation , the Admin API needs (username , password ) to authenticate .
But API Tokens are currently only linked to an organization and an organization role , please see these links :
https://grafana.com/docs/grafana/latest/http_api/admin/
https://grafana.com/docs/grafana/latest/http_api/auth/
https://grafana.com/docs/grafana/latest/tutorials/api_org_token_howto/

Does keycloak provide a way to distinguish between logins by the same user on different devices

Does keycloak provide a way to distinguish between logins by the same user on different devices (a user can be logged in on mobile device/s and also on desktop browser/s).
Does keycloak provide a way to identify when a user entered their credentials (whether through keycloak login or using an identity provider flow)?
Our use case is:
a user can request to reset their pin (from our app).
the user is logged out (a /logout using the 'keycloak-connect'
middleware).
following logout, the user is redirected to login and enters
credentials (keycloak or identity provider).
on login, the user is presented with the 'enter a new pin' page (our app).
To achieve this we want to be able to determine server side when to send the 'enter a new pin' page.
Our situation is that we don't easily know (for various reasons, including active keycloak session or other token expire/active states) when an actual 'credentials entered' login occurs.
Could the session_state from the keycloak access token be used to identify which keycloak session a client request corresponds to?
Could something like the following work:
the server receives the keycloak access token (containing the
session_state) from the keycloak login,
the server passes the session_state to the client (browser/mobile
app),
the client passes this session_state back to the server along with
the user requesting the action,
the server requests the session information from keycloak (something along the lines of making the following request to the admin REST API localhost:8080/auth/admin/realms/demo/users/{{user_id}}/sessions - then checking against session_state somehow?)
if the 'start' value of the session returned by the REST API is
recent, then maybe we have 'actual' login information?
We're still using Keycloak 6.0.1
Any help is greatly appreciated.
I wanted to update with how I'm proceeding, which I believe gives me all I want in terms of solving/answering my original question.
The keycloak access token includes: "sub", "auth_time" and "session_state".
{
"sub": "ae384e77-7588-444b-9c4f-3dc920750e1f",
"auth_time": 1590555910,
"session_state": "2d735372-1a5a-43de-8a6c-1a45deebf20b",
}
I can use the sub to query the Keycloak Admin REST API with https://my-domain.com/auth/admin/realms/demo/users/{{sub}}/sessions which gives a list like:
[
{
"id": "2d735372-1a5a-43de-8a6c-1a45deebf20b",
"username": "20000",
"userId": "ae384e77-7588-444b-9c4f-3dc920750e1f",
"ipAddress": "52.62.57.52",
"start": 1590555910000,
"lastAccess": 1590555910000,
"clients": {
"4eb676c2-94c3-4bac-a423-94a7bf57ece0": "demo"
}
}
]
I can then choose from the returned sessions list matching the id to the session_state from the access token (n.b., that start from the sessions list matches auth_time from the access token.
This gives me what I need. I can pass the original session_state to the client and request from keycloak matching that session_state :)
I'll update if I encounter issues.

What role is being checked by #RolesAllowed() in keycloak

I am using keycloak, and I have created a dropwizard service that I want to start enforcing roles in.
I have tried using the #RolesAllowd("user") annotation, but it always returns 403.
I have also tried #PermitAll, and that works fine.
I know I am connected correctly to the server, as the user has the correct information in it (email, name, etc), but where do the roles come from?
Is there a way to see the roles that a user has?
(answering my own question)
The issue that I was having #RolesAllowd("user") always returns a 403, is because of a checkbox in the Keycloak UI called "Scope Param Required". and the tooltip reads:
This role will be granted just if scope parameter with role name is used during authorization/token request.
It turns out, if you are trying to use that role, and the checkbox is on, it will not be sent to the client, so it will seem to the client that the user does not have that role. That checkbox was clicked ON for me, so that is why the annotation was showing the user was not authenticated.
So, if that checkbox is checked, you need to explicitly ask for the role, here is how you do that with user:
"scope" : {
"realm" : [ "user" ]
}
And here is more information from Keyclaok: https://issues.jboss.org/browse/KEYCLOAK-231
In your application realm on the keycloak admin console, you have a section called roles. There you must add the roles that will be checked by java security.
If you want that a user after a registration automatically receive a role, you need to add this role into default roles (roles -> default roles). You can also add manually roles to existent users in users -(select a user)->role mapping->assigned roles