Could the ID for a user be retrieved to be sent as a SAML attribute to a Client?
Thank you.
I have not work with SAML before but I think that what you want can be done by:
Go to the Realm where the client is;
Go to the Client;
Select Mappers;
Click on [Create];
As mapper type chose Javascript Mapper;
In the script type user.id
Fill up the rest accordingly, and click [save];
As pointed out by #Jan Garaj in the comments:
Script for Javascript Mapper is (already/still) deprecated feature and
it may be removed in the further Keycloak release.
You can use a User Property Mapper:
Go to the Realm where the client is;
Go to the Client;
Select Mappers;
Click on [Create];
As mapper type chose User Property;
In the property type id
Fill up the rest accordingly, and click [save];
Related
I'd like to add dedicated scopes to a client so that it can access information from other clients.
Turning full access on works but grants too many permissions.
The scopes are already created with their respective clients. It is “only” a matter of assigning scope from client a to client b. I have a list of names and client ids available locally. How can I efficiently assign them via kcadm.sh?
I already tried with the network tab open but I couldn't wrap my head around what the logic behind assigning scopes is.
E.g., there is a
POST /admin/realms/master/clients/968c7b36-95dd-4121-b92b-37b324298890/scope-mappings/realm with an empty array as payload
POST /admin/realms/master/clients/968c7b36-95dd-4121-b92b-37b324298890/scope-mappings/clients/74cb7b05-34d5-4657-8fe6-bb19a7c8a07f from the APIDOC it just says client. But I don't know what that client should be.
How to reproduce on Keycloak (X) 20.0.3
Login to the Keycloak Admin Console
Click on the client tab
Click createClient
Create client id and click next.
Click save.
On the new client. Click on the upper tab 'Client scopes'.
Click on the first blue item.
Click on the upper tab 'scope' and turn off full scope allowed.
Click assign role and add one of the items.
This is what I want to achieve with the help of the kcadm.sh as clients are added dynamically. You can't even export the client from Actions->Export and Import it again from the UI. Every scope is lost when imported again.
To assign role from client A to client B at the bear minimal you need the following Rest Full API call:
POST /admin/realms/ <REALM NAME> /clients/< ID OF THE CLIENT >/scope-mappings/clients/< ID OF THE CLIENT where the role comes from>
so in your case /admin/realms/ <REALM NAME> /clients/< ID OF CLIENT B >/scope-mappings/clients/ < ID OF CLIENT A>
the payload should be [{"id":"<ID OF ROLE>","name":"<ROLE NAME>"}]
You will need the call to get the id of the client for that you can call:
GET /{realm}/clients
with clientId as query parameter.
And then you will need the call to get the ID of the role, for that you can use:
GET /{realm}/clients/{id}/roles/{role-name}
id is the id of the client.
I'm upgrading my Keycloak from 16 to 20.
In 16 I could use this screen to add a custom mapper.
In 20.0.2 I can't find this form in the admin panel. There is a Client scopes tab for each client, and it has an add button. But it does not allow me to define my custom mapper. I just adds predefined mappers.
Where is that form?
How can I add custom mapper to a client in Keycloak 20.0.2?
IMO the old ui was a bit more intuitive in this regard. With the new one you need to:
Go to your Realm
Go to Clients and click on your client
switch to 'Client Scopes'
In the 'Assigned client scope' click on your client-id-dedicated:
then you go to the following menu:
Click on 'Configure a new Mapper' and then select 'User Attribute' and you get something as follow:
I'm still learning REST API principles and this one still confuses me. Password inside User Resource is private and of course cannot be placed in a response, while sometimes we need to get user data for public (e.g. when someone seeing someone else's user page). How do we handle this based on REST API principles? Should I remove password inside response before sending it?
Yes, you should not return the password in response. I would suggest you should create two DTOs
UserInputDTO: This contains the password and other values
UserOutputDTO: Here you have only those fields which are useful for the output and we can exclude password field and fields related to your internal implementation.
If your input and output looks same then you can add JsonIgnore annotation on the password field.
If by removing you meant setting it null then still the user can see the fieldname password, and if at any time you forgot to set it null then it will be a security issue. To solve this issue, you can use the JsonIgnore annotation.
I've got Keycloak setup and running with NodeJS.
I see you can create groups and assign attributes to those groups. Is it possible to access these attributes from the NodeJS application?
I can't even find the groups let alone their attributes.
Yes you can. But there is almost no official documentation on how to achieve this. You can return most keycloak attributes, groups and roles through the client mappers. By default none are configured.
To configure extra mappers: In the administration console, select the client and then the Mappers tab. That should bring you to a list of mappers.
You can add mappers here of different types. Once you add a mapper you can decide which calls to Keycloak from the client return the attribute(s), and what the name of the returned attribute is. The following screenshot includes a mapper that returns a dictionary of groups, with subgroups, separated by forward slashes. Your Node code will need to parse the returned JSON object.
All the information is returned in the keycloak token, which is a Javascript Web Token. In Node you can examine it by printing the token to the log. The keycloak-connect middleware stores tokens etc in an object on the request called kauth. The path to retrieve a list of groups specified by the configuration in the above screenshot is shown below. If you change the token claim name in the configuration, you will need to change the path in your NodeJS code accordingly. You will need to logout from your application and login again for changes to the mapper to work.
router.get('/', async function(req, res){
console.log(req.kauth.grant.access_token.content.groups) ..
}
I have a multi-tenant app in which user can select "current company" after they log in.
There is a DB per company but the model is the same, the workflow is the same, and the controller actions are same....The user can switch companies while being logged in and all actions need to be 'directed' to proper DB.
I know it is possible to customize context creation in EFContextProvider<T> by overriding CreateContext() but how do I pass the extra info (parameter, e.g. CompanyId) that would allow me to create context with correct connection string?
Is this possible?
I find the easiest way is to include the tenant id in a custom HTTP header.
Because the tenant id changes during the session, you probably want to create a custom Breeze ajax adapter (wrap the one you're using now) that sets this header dynamically during its implementation of the ajax method.
On the server you fish the header out of the request.
MAKE SURE YOU ARE VALIDATING USER AND HEADER ON THE SERVER