Keycloak : update user email from external IDP after first login - keycloak

I've successfully set up an external IDP in Keycloak with OIDC.
User is created if it doesn't exist in Keycloak realm, and is linked if it already exists. I've slightly altered the first broker login flow to implement this.
We've disabled email update feature in our app, as the trust source for this information is the external IDP. Now how can I force Keycloak to update the user email at login time if it has been changed in external IDP ? This informations is provided by the external IDP.
My knowledge of Keycloak login flows is not really good, so at least any hints / pointers on "how to to it" would be greatly appreciated. Thank you.

Related

Keycloak 18 proper configuration

I am using Keycloak to authenticate a user for a Vaadin application. The Vaadin application creates its own user session after successful authentication with Keycloak. I need the user to be able to change the password and email address.
Now I do not quite understand how to implement it correctly. There is a user Keycloak console that has this kind of functionality. But, for example, when a user changes their email address, the user is not prompted to confirm that new email address until a new login. Should I disable the Keycloak user console and e.g. use the Keycloak REST API directly from the Vaadin app to perform email/password changes? Or should I keep using Keycloak's custom console and configure it there?
What is the proper way to deal with such things with Keycloak? In case of Keycloak API I'd really appreciate the examples of API calls which should I perform in order to change the user password and email.

Shibboleth IdP - allow users to choose password or SAML login flow

I have implemented a shibboleth idp (myidp.example.com) on my own server with password flow. They authenticate with their username and password against database MySQL.
At this point, everything is fine.
But now I want to add one more login flow: SAML. I want to allow users to choose either login in by username/password or through another idp (idp.anotherwebsite.com). It's up to them to choose which method to login.
I've read through the entire shibboleth wiki, but it seems none of the articles mentions about my use case.
Can someone point me some direction?
You have implemented one idp.
Now for authentication page, you might need to implement one SP.
This is a normal usecase. Search for Federeted login.
Softwares like KeyCloak may help as well

OpenID connect VS SAML flows

I am currently going through OneLogin's documentation.
There is one point that remains unclear to me.
I think I understand the main differences between SAML and OIDC.
However on the SAML description it seems that there is no authentication required from the end user.
Compared to the OIDC description, where a code is required from the end user.
This point only would make me lean toward SAML as it is "frictionless".
My questions are -knowing that I want to integrate with OneLogin-:
Is SAML "frictionless"? Can it be?
Is OIDC "frictionless"? Can it be?
If so, is it a specific OneLogin feature? (It seems that all the documentation that I found online mention authentication with the IdP)
Thank you for your help!
The article states:
"The user either has an existing active browser session with the identity provider or establishes one by logging into the identity provider."
So the user has to authenticate if no existing browser session.
The article is around SSO i.e. if you have already logged into an IDP with SAML and you access another application on that same IDP, you won't have to login again.
OIDC has the same approach.
OIDC can be "frictionless" if you use the Resource Owner Password flow where you pass the user name and password under the hood. The user does not have to authenticate.
But it's deprecated in OAuth 2.1 as it's not secure.

Flask-OIDC | How to call a specific function after the user logged in

I built a login system using Flask OIDC and Keycloak. In my system, there is some endpoints decorated with oidc.require_login() that calls the Keycloak login page.
My goal is, after the user successfully logged in, my system checks if the user name exists in a specific database.
How can I set a function to be called every time someone successfully logged in with Keycloak and do this verification at the database?
According to your needs there are several ways to create the user in the backend.
The easiest way would be to just check the JWT token on every request. OIDC is based on JWT and that token is available on any request (which should already be done to find user roles etc). So your application can check that JWT and extract the username from it (see here for details about the JWT format). With the username you can check your internal database and create the user, if it doesnt exist. But at that time you'll not have access to any user credentials any more. It is just SSO and you need to trust Keycloak and the JWT... Also - you'll never be informed, if the user will be deleted in Keycloak, which could be an issue.
There is a callback API in Keycloak in form of the Admin URL per client. But the documentation is not clear. It says: It’s used by the Keycloak server to send backend requests to the application for various tasks, like logout users or push revocation policies. But I cannot find a complete list of "tasks". I saw only logout events. see Keycloak documentation and the documentation only talks about that. If I add an admin url to a test client, I did not get any requests at login time.
a different but more complicated way would be to create your own UserStorage SPI in Keycloak. It would be Java of course, but only some classes. There is an HTTP example or have a look at the LDAP user storage SPI, which supports registration too. If you choose that for your realm and a user tries to login to Keycloak (Login form), the SPI can call your backend to check the user. It also could be "used" to create the user in the backend by checking the Keycloak local storage and only if there is a local Keycloak user, call the backend. That isn't the reason, why you should implement the UserStorage SPI, but it's possible. If you think, this is a good idea, I would prefer to use your backend storage as the one and only storage or build a different one, that then could call your real backend in case of a new user. I would use this one by not using Keycloak local stored users but, by using your own database.
next (maybe last one). You can write an EventListener SPI to read all events and only filter the login events, see here and here. I think, that would be the easiest one. But be aware. In that case, the HTTP call to your backend coming from the event itself is based on a normal HTTP request (without OIDC at that time).
The last two examples create a JAR (which is explained in the links). That JAR with the SPI must be deployed in keycloaks standalone/deployments folder. The EventListener should be active by default, the UserStorage SPI must be activated per realm.
But - be aware - Keycloak/SSO/JWT - should not be used by creating users in multiple backends. Syncing the users between all backends in a SSO environment is maybe the wrong way. Most information is located in the JWT or can be called by a backend from one central user identity management. Do not store a user more then once. If you need the user reference in your backend - link just to the username or userid (string) instead of a complete entity.
There is no direct way of doing this, other sotfware like Openam, Okta allow you to trigger specific flows in a post-login configuration.
In keycloak, you can try to create your custom authn flow(using Default Identity Provider, its the only option that allow a redirect), and then select this flow in your Identity provider in post login flow.
The idea here is that after login, the user will be redirected to a link ( an api call that will verify his presence on the external database, and sent him back to keycloak once the verification is done.
More info here

SAML2 Multiple Service Providers

We have single sign on implemented in our web product(app1) using SAML 2.0 - our product is the service provider. Now one of our clients is asking for a link in app1 which will take the user to their web app(app2) and they are expecting the user to single sign on into their application. I am assuming that their app(app2) will be using the same IDP as app1 is using.
Based on my understanding I think a link to their AssertionConsumer of app2 should do the work. When the link to the app2 is clicked app2's AssertionConsumer will be able to process the claims from app1. Will appreciate if someone will chime in and let me know if I am missing something.
You should not link to the Assertion consumer URL. You link to the relevant page in app2. App2 will detect that the user is not authenticated and send it to IDP for authentication. The IDP will detect that the user is already authenticated and return the user to the page it was originally sent to.
Does app2 do passive auth when users arrive? If so, you should just link to any page in app2 and let it take care of asking the IdP about the user's login status, rather than trying to tell it.
If app2 doesn't automatically check with the IdP, then you should probably link to a page in app2 that requires auth, so that it will.
In general, the whole point of the IdP is that it's the thing that the SPs trust to tell them whether (and how) a user is authenticated, so you shouldn't try to build an additional system of trust between the SPs. (It's fine if they hint to each other that the current user is logged in or even someone in particular, but they should check with the IdP before believing it.)