SSO impossible from Direct Grant app to redirected app?

Hi all,

newcomer here. I have been wrapping my head around this problem and I suspect that it’s not possible. I’m asking for confirmation and advice as to how to proceed.

I have 2 apps, which we will call “origin” and “destination”. I need to enable SSO navigation from “origin” to “destination”. Both use the same Keycloak instance.
This would be easy if both apps used redirection… but they don’t, “origin” uses direct grant access.

The end-user logs in to “origin” by providing directly login + password to the app UI, the UI establishes a WebSocket with its backend and uses it to send the user credentials, the backend calls the Keycloak API with login + password and gets tokens for all further operations (API access).
There is one session per WebSocket, the UI never ever knows about tokens or Keycloak but just calls the backend that has the tokens, and when the user logs out the WebSocket is closed and the backend container is destroyed.

“Destination” is more classic, it uses Keycloak normally with redirection.

I want the user to be able to navigate to “destination” without being asked for credentials.

From what I’ve found online, this seems impossible.
Ref:

So my questions are…

  • is it possible?
  • could the “origin” app put its tokens in a cookie that would be found by the “destination” app, or more accurately by its Keycloak login UI?
  • could the “origin” app call some Keycloak API to inform it that “destination” app can be considered logged in with the same tokens? So that when the “destination” app tries to log in, Keycloak doesn’t even ask for credentials.
  • is there any other workaround? In the long term I could ask “origin” to use redirection, but a short term hack would be cool.

I should add that I’m not an authent expert. I have worked with SAML2 in the past so I understand the big picture, but I’m not much at ease with the different tokens (authent, authorization), what their scope is and what they are associated to. (I know that there’s token and renewal token, but I think that’s out of scope here)

Any help or advice appreciated :slight_smile:

1 Like

I’m in a very similar situation… have you managed to get to anything? I’m able to authenticate via a plain HTTP call on the origin, but I wonder how I can pass that authentication information to the destination… I thought I could set a KEYCLOAK_ADAPTER_STATE

Hello,

I would like to know if you have solved this case.
If yes, could you explain how you solved it?

Regards,
Kamil

Hi all, to those following this topic, we have still not gotten this working, nor have we yet set up a plan B. Issue is still on the table.

The only way that comes to my mind is to use temporal user fingerprinting (FP)
Like, getting all the information that comes in the request headers from the client, and making a temporal internal ID out of it. Among those FP headers are:

When client first logs into keycloak, you save the logged state for the user with that FingerPrint.
If the seccond UI is accessed, in the backend part you would check the client’s fingerprint and if it matches one saved in your system return the mapped token and/or give access to the client.

Still seems a bad idea to me. but hey, it’s a way.

Thanks for the suggestion (and thanks for keeping this topic alive :wink: )

I would possibly do that if this were a personal project. But without being a security expert I have a hunch that this would be deemed unsufficient in a pro environment, for a product.

Hi, I am working currently on a project based on Keycloak where i had similar requirement for Direct Grant/Browser Flow, simultaneous login feature. I don’t know much about your “origin” app, but my workaround looked like this:

I’ve extended OpenID protocol in keycloak (token endpoint) by:
> checking for my custom scope in request (ex. “login_cookie”)
> changing token issuer (it was necessary in my case - different domains)
> based on above, invoking AuthenticationManager.createLoginCookie(…)
(at this point, besides openID token response i’ve got also KeyCloak cookies - set headers)

to sum up, with this extension, i’am able to login in using client backend (DirectGrant - OpenID), and use KEYCLOAK_IDENTITY cookie for frontend authorization in WEB via client app. So it all depends if you are able to set keycloak cookies on client application (“origin”) side. If you would need more explanation i would be happy to help.

Let me refomulate to be sure I understand.

You are saying that you actually modified your Keycloak code, right? You patched it, basically.
(and by the way this modification is on all endpoints, it’s not restricted to a given realm or client?)

Also, the origin app needs to be able to set a cookie.

Did I understand these two things correctly?

Thanks!

  1. Yes
    Look at this paragraph, it’s about customizing service providers (basically customizing keycloak).
    https://www.keycloak.org/docs/latest/server_development/#_providers.
    … i extended OpenID protocol provider ifself, which is global (not per realm or client) :wink: .

  2. Yes
    In your response you would get “Set-Cookie” header(headers), with KEYCLOAK_IDENTITY cookie which contains keycloak session JWT.

1 Like

In the end this is what was done, it works more or less: “origin” gets the JWT from the backend. It sets the JWT on the URL calling “destination”, which uses it to say it’s logged in. (the JWT is a URL param)

As a consequence both apps are seen as the same from the identity manager (Keycloak). But the user does not have to authenticate when arriving in “destination”.

“destination” had to be slightly modified for this.

Hello, jrobinss
We implement SSO from direct to browser flow through setting Cookie from direct grant endpoint. Our app open webview with cookie from direct grant REST API

1 Like

can you explain this in more detail?

Well, I don’t really see any more detail to add… :-/
Let’s try.

Basically the idea is to treat both apps as one app, and use navigation URL to share data.
So, the first app to get any credentials stores them, and when a link is clicked, it adds its credentials to the link and calls the other app.
The other app is called, and is modified to know that it should get a new param in the link, with the credentials. It uses this to call anything else.

Notice that I say “credentials”, in fact it’s a JWT, but the mechanism is fairly generic.

That’s why I say that both apps are seen as only one by Keycloak. Keycloak is not aware of this little JWT sharing trick. From its point of view, it delivers a JWT once and that’s it.

Hope that’s more clear.

I should add that in the team where I work, I was not the one who actually implemented the solution, so there may be some level of detail that I’m missing. (I don’t think so, but it’s always possible)

Hi All,

I also have a similar issue.

I have an application: say Application1 without keycloak

I have integrated Eclipse Che into Application1.
Now what I want is, if I login to my Application1 (without keycloak), I should be able to call some API of keycloak to login to Eclipse Che (without rendering keycloak’s login page).

Is this feasible? If yes, how?

Any help will be highly appreciated.

There were several solutions in this thread, none very convincing… My solution requires to modify the second app, so in your case modify Eclipse Che.

Maybe also check out token exchange in case it’s what you want
Keycloak token exchange