Hi all,
I trying to integrate external idp to Keycloak server. That external idp has no any adapter that supported by Keycloak(SAML, OIDC), it only support API. Until this time, I tried script execution in browser flow I can reach the external idp and validate user but how can I authenticate that user also in Keycloak too?
Is there any options for some kinda group based authentication in Keycloak ? or
Can I authenticate user in script, I did not see something like that but I still suspicious.
I am open to any advice.
Hi @guenoledc and thank you so much for your advice:)
I will try this approach immediately but before start to implement I have a doubt ;
I thought this method wont effect my token mechanism right?
Keycloak will produce same tokens as in OIDC flow and those token going to may introspect by Keycloak ?
The solution connects behind keycloak IDP services and it works with both OIDC and SAML. For keycloak it is a AuthenticatorSPI. So Keycloak external interface is not impacted.
So I tried this cool method and it work. What a great article @guenoledc
But I guess user must be defined already in keycloak otherwise I getting âInvalid username or passwordâ. How can I skip this check. I need authenticate the user who does not exists in Keycloak via external Idp.
So you should test this and either respond with a challenge form to ask the user for his email or other id and process that info in the processInteraction method or have another way to identify your user (cookies, ip address, âŠ) using the other elements of the AuthenticationRequest
Thanks for your time.I got it whats your point. What about the Username Password form ? Do I have to modified it? Cause its blocking me if user does not exist.
In the authentication flow you should have in that order
authentication via session (alternative)
authentication via Kerberos (alternative but i guess you are not using it so tou can remove it)
authentication via identity providers (alternative)
authentication via your external service (alternative)
forms (alternative) - with inside forms and checks
So your service gets hit before the conventional forms are displayed. And you can display the forms you like , such as asking for the user name and optionally the password
Can you screen shot your flows and explain what your external service does?
Actually there is no implantation yet, I am in discovery stage
I did implement example that you put in article.
I observed, if username or password wrong then flow never direct to my service.
I need like a fall-through mechanism;
Is it contain in Keycloak.If dont,
Then check rest authenticator for external idp has it or not.
If external idp has it, then authenticate user and return id_token, access_token and refresh_token.
Ok so you are at the stage where we need to reason on the sequence of the actions.
So could you clarify a couple of points
your external IDP (reachable va APIs) contains all or a portions of your users ?
if authenticated once with your external IDP, do you expect the user to be added in keycloak for future authentication (like in a migration scenario)?
Regarding the current flow of your screenshot, the ârest authenticatorâ is called but receives no information about the user. So, rather than adding the âuser password formâ below, it is the rest authenticator that should respond with this form as a challenge so your rest authenticator can receive the username and password.
So your authenticator can return something like
return {
authNote: { someState: "data that you will retrieve at next call" },
challenge: {
formName: "login.ftl",
message: "Enter your username and password",
formData: {
login: {
username: "username that you could deduce from an hint to prefill the form"
}
}
}
Then when the form is submitted it is your rest authenticator that will receive the form values (username and password) in the AuthenticationRequest.httpRequest.formParams
Looks like another great features.
I got your suggestion. This way I will able to be the one who provide login screen and I will able to get username, password etc. but my inference is, it is not possible to generate any token without user information. It is possible with adding those âforeignâ users into keycloak. My point is I can not get id_token and access_token if user does not exists in Keycloak.This is the reason why you did suggest ;
" if authenticated once with your external IDP, do you expect the user to be added in keycloak for future authentication (like in a migration scenario)?"
So, I have to consider about migrating scenario. Maybe I will add users in keycloak for a while and after they logout or their session terminated, I can delete users from keycloak. What you think about that flow.Is it sense ?
If I am not mistaking, if you authenticate your users directly against your own system, then keycloak would not be able to create tokens since it has no user in its session. This was something I did not consider in my initial use cases, so with version 0.1.x it is not possible, unless to feed keycloak using its admin APIs.
I just realize that and created the version 0.2.0 of the library to handle this, creating the user in keycloak on the authenticatorâs response when some info are provided
So, update the library to version 0.2.0 and use the following code example (typescript)
And for your migration point, it depends wether your legacy system is there to stay or wether you intend to put your users info and credentials in keycloak in the long run.
Assuming you wand to migrate, there are a couple of points to consider
your custom authenticator is before the default Browser Forms so it must know if the user is already created in keycloak
but you do not know the username yet, so you need to ask and refer to keycloak to know if it has been created
since you prompted yourself the user, you cannot let the default forms take over the flow
you would need to play with a âpassword only formâ and the password authenticator
I have not tested that but I can try if you are interested
Thank you so much @guenoledc for all your helps.
I am really so appreciate
I will test structure that your proposed and of course I will update here for the others.