How to disable the SSO feature in the Keycloak - keycloak

I want to use Keycloak as an identity provider in our company.
I have defined one Realm with three clients (I have three applications and I have defined a client for each application)
I want to separate the process of login and logout for each application. For example when I login into app1 and app2 and app3, and then logout from app1, the app2 and app3 remain logged in.
In StackOverflow I found some solution to separate the login process for each application as follow:
1. in admin console, go to Authentication
2. make a copy of Browser flow
3. in this new flow, disable or delete Cookie
4. go to Clients -> (your client) -> Authentication Flow Overrides, change Browser Flow to your new flow, click Save."
How to force login per client with keycloak (¿best practice?)
But this solution is not working for making the logout process independent for each application(which means I want to disable the SSO feature in Keycloak). Is there any way to make it possible?

I would enable Direct Access Grants on the client level only (Standard Flow will be disabled), so applications will have to use direct grant flow. No IdP sessions in the user browser will be created in this case, so no SSO will be used.

Related

Do not show ANY login form in keycloak but call directly the custom IDP authentication endpoint

We have our own CRM portals and we want to offer OpenID based User authentication and authorization.
To achieve this we have decided to use Keycloak.
The flow we formalized is below and we are stuck due to may be not knowing much of the configurations inside Keycloak or may be its not possible.
User visits our existing CRM login page where he/she provides the username and password.
On click of Login the keycloak custom Identity provider should authenticate the user
Keycloak should receive the authentication success response and generate the JWT token
User is redirected back to CRM dashboard with the help of redirect_url configured in custom IDP.
What we have done till now,
Created a custom IDP inside Keycloak.
Configured all endpoints in this custom IDP
No custom authentication flow yet, all defaults i.e. First login flow is set to 'first broker login'
Challenges we are facing currently,
User on our CRM login page (Not the keycloak login form) and click on login button
The Keycloak login form is shown to user. We dont want any keycloak login pages. but instead the custom IDP endpoints should be executed and a JWT is returned back to redirected CRM application.
Is this possible to achieve the flow I mentioned above?
You need to adapt the browser Authentication Flow
Authentication -> Flows -> Browser
There you find the Identity Provider Redirector. Click Configure and specify a Default Identity Provider (you need the alias of your IDP there)
Normally all available IdentityProviders are listed beside the login form. But if a DefaultIdentityProvider is configured, KC immediately redirects to the external IDP.

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

Unique login for multiple clients in KeyCloak

In Keycloak, is it possible to have only one login for all the clients in the same realms? I have configured the server (from the admin console) in this way:
- create a new realm (let's call MyRealm);
- create two different clients (Client1 and Client2)
- create a user (Alice)
I have tested the two clients individually, and they works fine (the default keycloak login page appear and if I provide the credentials the browser redirects me correctly); the problem is that when I am logged in in Client1, and go (from the same browser) to Client2 the login page re-appers. Is it possible to configure the server in a way that I have to log in only with one client, and then I am authenticated also in all other Realm's clients? Thanks.
I solved this problem configuring only one client (named UniqueClient) from Keycloak admin console; then I modified the two java applications (Client1 and Client2) and now all of them are pointing to UniqueClient (in their keycloak.json there is 'clientId': 'UniqueClient'): in this way when I start one of them the keycloak login page appears, and if I log in, I'm logged in also for the other application (unitil the session expires);
You can achieve this by using https://github.com/IdentityModel/oidc-client-js/wiki so you will be logged in several clients at the same time on the same realm

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.)

sso and slo on multiple applications

We need to implement an single sign on and single sign out solution for multiple applications (not in same domain and different permissions per application) having one authorization server.
Scenario 1:
If we setup one client_id: "global" with scopes: "app1,app2,app3" on auth server user is authenticated in ALL apps and user has one cookie for auth server and one cookie for each app he opens.
Problem here is that a user that has access to app1 and app2 and NOT on app3 is getting authenticated for all apps from auth server. So authorization should take place on application level.
Single sign out looks simple. Lets assume that user logout from app1, so he gets redirected to auth server and auth cookie is deleted. After he gets back to app1.domain/logout and app1 cookie is deleted as well. Authentication server is responsible to POST requests to app2.domain/logout and app3.domain/logout to delete all other cookies as well.
Scenario 2:
Each application has it's own client_id, for
For example:client_id:"app1" with scopes:"user"
client_id:"app2" with scopes:"user,public_repo"
client_id:"app3" with scopes:"admin"
When user login through app1, code-token exchange take place with auth server by using as client_id: "app1". Two cookies are now created one on auth server and another one for app1. When user now navigates to app2, another request take place by using client_id: "app2" and auth server is not able to authenticate user to app2 now. How is this feasible??
This setup does not look like and sso but looks more abstract than Scenario 1.
Any ideas/suggestions would be appreciated.
Thank you