I am currently using the JavaScript adapter to retrieve the profile for the currently logged in user via the loadUserProfile() function. Is it possible to control what properties and attributes are returned in this profile object returned?
I have some custom attributes set against the user account in my Keycloak server which I do see coming back.
I then noticed I could add a 'User Address' mapper for my client which I have added and was hoping I would see this come back in the loadUserProfile but it does not show up.
I have made sure the 'Add to userinfo' toggle button is enabled for the address mapper I have added. I assume though this option is only for when retrieving from the userinfo endpoint, not this user profile function I am calling through the JavaScript adapter.
Can I get this address field to show in the profile response, or do I have to have custom address attribute configured and set on the user in the Keycloak admin portal?
The client mappers are meant to put (or not) user attributes into the tokens (idtoken and/or access token), if you inspect idTokenParsed object for instance , you will see your address object in there. loadUserProfile() just calls the user account endpoint and is unrelated to these client mappers.
Related
is there any way to link end-user to register with attribute somehow incorporated?
For example:
User needs attribute customerId to access the data.
I'll send him a link to register with his customer id already in it.
PS: will be using OAuth too so there is no way of creating premade account with temporary password
I'm using Keycloak for Identity Brokering through Google, Microsoft, etc. But Keycloak only allows one email per user. So the user can be authenticated only through one of the social login options (Google if gmail is added as user's email address, etc.). Is there any way to include more than one email per user, or any other workaround?
EDIT: (Editing based on comments to make scenario more clear)
In my scenario, I'm using a federated user store which contains a large number of users and and I need Keycloak to access all the emails linked to a user when that user is logging in using Google,Azure,etc. because Keycloak is using the email as the unique identifier for the authentication response from the social login provider. Without having the required email as the main email, Keycloak won't allow that user to log in through social IdP
Although, Keycloak emphasises on keeping a unique email,but there are certain scenarios where you may want to keep , say, secondary email.
This can be achieved in a couple of steps:
1. Add a custom attribute for secondary email in user like this:
2. Next , in your client create attribute mapper like this:
When I generated the token after above configuration, the new attribute was avialble in token. You can use this attribute in your app as you desire.
Parsed JWT:
I figured out the best way to deal with this is through the custom user provider (federated user store). Even though we can't add multiple emails per user through the Keycloak admin console, we can write the user provider in such a way that it can get all the emails linked to a user from our database and assign them to the email attribute of each user. Once this is done, all the emails will appear on the admin console as well.
For the social login to recognize those emails, we have to get all the emails linked to a user in the provider to an array and iterate through it until the authentication is complete. This would help to create the social login link to the user through First Login Broker authentication flow.
This is a crude way to approach this, but nevertheless it works!
I want to secure my user registration page with keycloak but couldn't think of any approaches while reading the docs.
Use case:
The registration page for new users shouldn't be public. New user get an invitation email from the admin. The email contains a link to the registration page.
I thought about using an initial access token (like for client registration) and add it to the link to the registration page. Afaik there is nothing like that for user registration?
Are there any other ways to do it?
I think you've got two options to implement it:
First
You know the e-mail of the destination user before sending the invitation, so you would let the admin create a user in keycloak with the e-mail itself as the username. Then the admin should check 'Verify e-mail', 'Update profile' and 'Update password' as required actions, so keycloak will send an activation mail (you can customize the e-mail template) and user will be required to fill his data and set a password.
If you don't want the admin to access keycloak directly, you could do it via the user management API.
Second
Implement this logic in your application. Write a user data form which is publicly accessible using a code (it might be some UUID). When admin sending the invitation mail, link a random code to the address, so when user enters the page, you can verify it. Then you'll need to save the data in keycloak as a new user, using the user management API.
I'm working on a multi tenant project where usernames are actually their email addresses and the domain of the email serves as a tenant identifier.
Now in keycloak I'll have different realms per tenant, but I want to have a single login page for all tenants and the actual realm that will do the authentication to be somehow resolved by the username (email address).
How do I go about doing that?
I found a thread on the mailing list (that I cant find now...) that discussed the same problem. It was something along the lines of - create a main realm that will "proxy" to the others, but I'm not quite sure how to do that.
I think Michał Łazowik's answer is on the right track, but for Single-Sign-On to work, it needs to be extended a little.
Keep in mind that because of KEYCLOAK-4593 if we have > 100 realms we may have to have multiple Keycloak servers also.
We'll need:
A separate HTTP server specifically for this purpose, auth-redirector.example.com.
An algorithm to determine the Keycloak server and realm from a username (email address).
Here would be the entire OAuth2 Authorization Code Flow:
An application discovers the user wants to log in. Before multiple realms, the realm's name would be a constant, so the application would redirect to:
https://keycloak.example.com/auth/realms/realname/protocol/openid-connect/auth?$get_params
Instead, it redirects to
https://auth-redirector.example.com/?$get_params
auth-redirector determines if it itself has a valid access token for this session, perhaps having to refresh the access token first from the Keycloak server that issued it (the user could have logged out and is trying to login as a different user that is served by a different realm).
If it has an valid access token we can determine the Keycloak server and realm from the username or email address in the access token and redirect to:
https://$keycloak_server/auth/$realm/realname/protocol/openid-connect/auth?$get_params
from here, the OAuth2 Authorization Code Flow proceeds as usual.
Else if it doesn't have a a valid access token, the auth-redirector stores the original app's $get_params as session data. It presents a form to the user asking for a username. When the user submits that, we can determine the Keycloak server and realm to use and then auth-redirector itself logs in to the Keycloak server using its own $get_params. Once the auth-redirector gets a call-back, it retrieves the access+refresh token from the Keycloak server and stores them in session data. It then, finally, redirects back to that same keycloak server and realm with the callers original $get_params (from session data). And the OAuth2 Authorization Code Flow proceeds as usual.
This is definitely a hack! But I think it could work. I'd love to try it out some day, time permitting.
Other hacks/solutions are needed for other OAuth2 flows...
The idea from the mailing list is to write a service (let's say auth-redirector.example.com) that has a single input field for email, finds realm based on domain and redirects to that realm's keycloak endpoint (e.g. auth.example.com/auth/realms/realm-name/etc…) while keeping all GET params.
You can find examples of direct login/registration URLs here: https://lists.jboss.org/pipermail/keycloak-user/2016-July/007045.html
One usability problem is that users would have to provide their email twice, I have not yet found a way to pass the username via the login URL.
We have a Portlet running on Java/J2EE technology. It interacts with another application/system through HTTP request that requires user authentication. The current solution retrieves logged in user's user name and password from the Portal, and passes this information to back end systems using "HTTPClient" API's to retrieve content based on user's authentication and authorization.
There are efforts to enable site minder for the Portal. With site minder enablement, the Portal no longer provides logged in user's user name and password. The ideal way would be that back end application also has site minder enabled so that Portlet could pass the login token or cookie value.
Looking for interim approaches until the back end application is SiteMinder enabled. Is there a way we can enable/force user to enter user name and password ? I cannot think of such possibility because the Portlet code (using HTTP Client accesses the back end URL of the application, its not the browser). One possible way I can think of is, develop a new screen(UI) to have user enter user name and password within the Portlet and use that to authenticate with back end system through Java code. Please let me know if any other ideas.
Also, let me know if the question is confusing, I will provide more details.
Thanks
Siteminder can provide user information dynamically to connected applications in HTTP headers (uid, email address, etc.). This behaviour is configured on the Siteminder Policy Server. By default, the HTTP header SM_USER (or similar) contains the username of the authenticated user.
Then, you have to adapt your portlet code to fetch those headers from the request and feed it to the back-end application like you used to.
I wouldn't advise the use of the SM_USER header for tracking users. SM_USER contains the ID that was provided to the credential collector, and will change based on the type of authentication scheme used.
Example:
If you have an HTML forms based auth scheme that collects email address instead of UserID, the email address will be sent in the SM_USER header. In the case of an X.509 auth scheme the SubjectDN from the certificate will be in the SM_USER header.
The better choice would be to use the SM_UNIVERSALID header as that will always contain the Universal ID attribute. The Universal ID attribute is configured in the User Directory object (typically this is set to "uid").