[keycloak-user] Transparent login for legacy web applications without direct Keycloak integration

Thomas Darimont thomas.darimont at googlemail.com
Fri Sep 1 16:59:45 EDT 2017


Hello,

Sorry for the long email...

A while ago I experimented with a Keycloak extension that would support
converting access_tokens,

retrieved via a Direct Access Grant, to a 307 redirect response with the
KEYCLOAK_IDENTITY,

KEYCLOAK_SESSION set to transparently authenticate a user.

The use case was to allow users to transparently authenticate via the login
pages of a legacy-app

(a portal, which I cannot change) without requiring users to use the
Keycloak login pages.

Next to the legacy application there are other newer apps which are fully
integrated with Keycloak.

Users who login to the legacy-app first should be able to access the other
applications without an

additional login step. The users of all applications are stored in Keycloak.

This and similar topics have come up quite often on this mailing list in
the past so I

wanted to discuss a potential solution, which uses Direct Access Grants, a
new hypothetical

“token2cookies” endpoint in Keycloak, as well as redirects.

It would work like this:

1) legacy-app sends a POST with client_credentials + user_credentials + a
generated nonce

to Keycloak to retrieve an access_token via Direct Access Grant.

The nonce is stored with the client session in Keycloak. The purpose of the
nonce is to prevent

attackers from issuing cookies for an access_token that was issued for a
different client or at a different time.

2) legacy-app extracts session_state from access_token, generates
"token2cookies" URL

and sends a 307 redirect to the users browser.
This URL contains the session_state, the nonce and the client_id to
redirect to as parameters.

E.g.:

Location:
https://sso.acme.local/auth/realms/transparent-login/protocol/openid-connect/token/introspect/t2c?redirect_to_client_id=legacy-app&session_state=680e5ba3-6f9f-4c79-9c74-a24347a06f63&nonce=b98cd9a7-c834-4942-bef7-aba90061582d

3) The browser follows the redirect.

The endpoint verifies the session_state by comparing the previously stored
nonce

given as URL parameter. If the session is verified & active the endpoint
performs some

checks with the user associated with the session (present, disabled, etc.).

If the user is valid then:

AuthenticationManager.createLoginCookie(session, realm, user, userSession,
uriInfo, clientConnection);

is called which generates and injects the KEYCLOAK_IDENTITY,
KEYCLOAK_SESSION cookies into the response,

which is then returned as a 307 redirect to the base_url configured for the
client referred to by the redirect_to_client_id parameter.

The redirect points to the
org.keycloak.services.resources.RealmsResource#getRedirect

endpoint which eventually redirects to the base path of the target
application.

This redirect URL looks like:

https://sso.acme.local/auth/realms/transparent-login/clients/legacy-app/redirect

The user is now returned to the legacy-app. He can now transparently go to
other applications e.g.

new-app without having to login again since the Keycloak session cookies
are now present for sso.acme.local.

The new-app will transparently renew the sso session.

I think this approach could be applied in many legacy integration scenarios
where users are used to access

a centralized application which, for whatever reason, cannot be changed
that much or fronted with Keycloak.

Looking forward to hear your opinions about this approach.

Cheers,

Thomas


More information about the keycloak-user mailing list