Identity brokering, upstream idp selection without exposing idps

Hi there,

I am seeking for a solution for quite some while now, and now that I have read a lot about keycloak and about the authentication mechanisms, as well as built some test setups, I have decided to ask here.

My goal is to connect some publicly available applications of my organization to a keycloak instance to allow both my own organization’s users (brokering with Azure AD) and also some customers’ users (brokering with whatever idp they use, or adding these users to keycloak as “local users” if the organization doesn’t have one).

Standard functionality is perfect here, BUT I don’t want customer A to see the button that also customer B is enabled as a idp provider for this keycloak instance. Assume you are from Mercedes and log in at some service provider’s dashboard, the provider doesl probably not want you to see he also has BMW as a customer… (not saying that we have either one of those as customers, just an example).

I know of the possibilities to directly “pass through” to an idp by usage of the kc_idp_hint, but this doesn’t help me really, as in order to to this I would have to have the same service on different domains in order to define different clients with different overrides of the browser flow.

What I WOULD like instead, is instead of the buttons displayed on the login page linking to the upstream IDPs, a field where the user can enter his domain name or his Email address, and based of the domain he gets forwarded to the identity provider matching the domain name. If no match, he gets a “sorry” and that’s it.

Would this be possible and if so, how? Has anybody implemented something like that? I don’t think my use case is so rare… Is the right way to implement such thing just a new template/theme to be developed?

Thanks in advance for any good ideas

Christian

What you are suggesting is possible using a custom Authenticator that can be added to the authentication flow. There is an example here: keycloak-extension-playground/auth-dynamic-idp-redirector-extension at master · thomasdarimont/keycloak-extension-playground · GitHub

Thanks a lot for pointing me to this example. Indeed, it looks like it should be doing exactly what I need.

Unfortunately, I may have some understanding problems and I can’t get it to work. Would be great to get any help on how to actually use this one correctly.

What I did / what works:
Together with a developer colleague of mine who is familiar with Java and maven, we have got the custom Authenticator compiled and added it to my Keycloak instance. After a restart (in my case, a redeployment of the container) of keycloak I can now find this in the authentication workflow to be added to flows. Unfortunately, either it doesn’t work or I don’t understand how to build a flow with this.

I have duplicated the existing “Browser” flow and added a new flow inside. Within this, I have added a “Username form” and the now newly available “Dynamic IDP Redirector” with a configuration of a domain name and an alias of a working upstream idp: “something.org/something” being “something” the actual name of an upstream SAML IdP (MS Azure AD) that works fine so far. I have then used this new Authentication flow as a override in one client’s configuration.

What happens now is that I get a “Username or Email” field only when being redirected to the keycloak login page which is nice. When I enter an email there with the “something.org” domain name I would expect the next step to be redirected to the “something” idp, instead I get “Invalid username or email” if the email is of a user that does not (yet?) exist in keycloak, and the same field again when it does actually exist.

I seem not to understand where the extension described in the link posted tries to get the user attributes from that it tries to use to extract the domain from. Maybe I am “holding it wrong” entirely, can anyone help me with a working configuration so I can understand how it is meant to work?

Thanks a lot in advance

Christian

@fibbs This authenticator uses an existing user. If an existing user specified in the “Username or Email” field has an email domain that matches the pattern, it redirects to the appropriate IdP.

If you want it to redirect just based on the input email domain, you should get rid of the user check in authenicate() and change the logic in determineTargetIdp() to use the input email domain.

OK, thanks for that valuable information. On the long run, this is probably what I want and I will have a look on that part. For now and now that I understand that part, I would like to get it to work “as is” first.

I got the redirect working with the following auth workflow #1:

That is pretty good already: I get a login window just presenting a username/email field, and if the email matches the domain I have configured to be tied to one upstream idp, I get redirected there, and if I manage to log on with this idp, I am in. Awesome! If a not existent user is typed in, I get “wrong username or password”, that’s the right direction.

But, if I enter a username or email address that is NOT defined in such a rule and should be handled “as normal”, logging in with username, password and OTP, I am wondering how to combine that with the “Fall back to Auth workflow” switch of the Dynamic IDP Redirector. I have tried something like the flow shown as #3 in above screenshot, but that doesn’t work:

A little more help on how to get this to work completely would be really awesome, if that is even possible.

Christian

Hey Fibbs,
Can we connect I am also working on the same use-case and can you explain how did you deploy the dynamic idp as I cannot see it in my admin console and also what all changes must be done to the code.
Your help would be highly appreciated!
Thanks!!