In Keycloak, can I specify kc_idp_hint for the built-in clients (e.g. security-admin-console)? - keycloak

I have an application that includes Keycloak as the identity component. I want to redirect to the Keycloak security admin console for a particular realm from my application, which I am able to do, however I also want to specify a particular IdP to sign in.
For my OIDC apps that are protected by the same Keycloak realm, I am able to do this using the kc_idp_hint query param. However the built-in clients don't seem to respect this, so the following URL does not result in the IdP hint being propagated to the authorization URL:
https://<keycloak>/admin/<realm>/console?kc_idp_hint=<idp>

Related

Reject users from external SAML IdP in Keycloak

I have a setup where my application uses Keycloak (version 20.0.2) as identity provider. Keycloak allows also delegating the login to some external IdP that responds with SAML token. I'm mapping the roles in Keycloak based on attributes in the token, which works fine. However, sometimes I would like to reject access for a user (if is does not have any roles assigned) or in some more complex scenario (user can access only if he has some attribute and role combination).
What is the easiest way to do that? Do I have to write my own SPI that will handle that (what kind of SPI?)?

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

Restrict front client connexion with groups / roles in a realm

I'm looking for a way to restrict user access to specific clients in a realm.
I know I can do it with client where Authorization is enabled (fine-grained authorization support) but it doesn't work when trying to connect from front (client need to be public and not confidential).
I'm using a javascript application to login from front-end.
Is there a way to enable Authorization for public client or a work around ?
Thanks.
I'm not sure if this will totally answer your question because it's still not specific enougth but it may give you some further help.
In case you're new to the topic, please see difference between public and confidential clients here.
The current best practice for public clients like HTML/Javascipt applications is to use OpenId Connect with the Authorization Code Flow + PKCE. HTTPS is of course a must have. I recommend you use a javascript openid connect adapter for this like the following for example:
https://github.com/panva/node-openid-client
Basically your authentication / authorization flow is shown here:
When the user wants to login from your frontend client application first a unique verifier is generated which is only available to the exact user / browser session. This value get's hashed as a code challege. Then the user gets redirected to the login page of your authorization server (Keycloak for example) passing some parameters like a redirect uri and the challenge.
With successful login the user get's a session at the keycloak server which also stores the hashed challenge. Then the user gets redirected to given redirect uri (a path in your application) together with a code to obtain an access token. Back in your application you application uses the original value together with the code to get the actual token. The authorization server ckecks the value against the stored challenge and geturns the access token if it matches. You see the extra verifier is to prevent that anybody compromises your code fragment to obtain a token on your behalf.
Now you have an encoded access token in your browser app. Note the token itself is normally only encoded not encrypted but it can be signed. Those signatures can later be used from your backend to ckeck the token integrity but we will come to that soon. Roles, claimes, scopes and so on included in your access token tell you the privileges of the user/identity. You can of course use them to enable/disable functions in your app, block routes etc. but in the end client protection is never really effective so your real authorization ande resource protection happens at your resource server which is your backend (node, .net core, java etc.) maybe a restful Web Api. You pass your access token as a part of the http request header with every request to the backend. Now your backend checks the token integrity (optional) expiration time etc. analyzes scopes, claimes and roles to restrict the resource access.
For example a simple GET myapi/car/{1} may only need a token or can even be annonymous while a POST myapi/cars or PUT myapi/car/{1} may need a special role or higher privileges.
Does that help you out?

Keycloak - Use legacy authentication system in a native mobile app

We are running some tests on Keycloak to implement it on our company and I am are wondering what is the best approach to make Keycloak interact with our legacy system.
In our scenario, we have a native login interface and we are going to use direct grant - we are not going to authorization code flow / redirect flow using a browser and we don't have any kind of social login.
The other point is: we must to keep our native interface.
Based on that, what is the best/right approach to implement this flow? I have set my client on Keycloak with direct grant but the problem is that every user must exists in Keycloak. Isn't possible to use Keycloak as a "token emissor" instead of IDP?
In case of Keycloak must be an IDP, what is the right approach to allow Keycloak log in legacy system? Should I implement a custom Identity Provider? Will mobile make a login request to Keycloak or to legacy system?
Keycloak must somehow be able to either authenticate the user or delegate the authentication of the user to a federated identity provider. A few options:
If you want to use Keycloak as an identity provider, you could do
this by migrating your user base to Keycloak, or by making use of
User Storage Federation, which means Keycloak will use your existing
user database as a source. In this case, the login interface will be
a Keycloak interface (which you can customize to your wishes). See:
https://www.keycloak.org/docs/latest/server_admin/#_user-storage-federation
Another option is to convert your legacy system into an identity
provider that complies with either the OIDC or SAML protocol, and
set it up as an identity provider for Keycloak. In this case you can
keep your existing login interface, but it will probably require
quite some changes to your legacy system. See:
https://www.keycloak.org/docs/latest/server_admin/#_identity_broker

Skip IDP authentication in SAML

I am creating a service provider which talks to third party IDP for authentication. But I have a concern that I have a set of dedicated machines(Desktop,tab) which are highly trusted, so is their a way in SAML that when a request is sent from such machines user is directly authenticated without the need to type username and password.
you want that user that tries to access a resource from his desktop (which is trusted) will be automatically authenticated? if this is the case, it seems that you need to identify the user using the active directory or something.
if this is the case, search a bit about Kerberos, or ADFS - it might serve your needs.