amdev
amdev

Reputation: 3249

OIDC Backchannel logout, how to kill browser session of a user from REST call in a JEE Application

We are using Keycloak as a SSO provider to login in all our application.

We are using the keycloak logout endpoint to logout at a realm level and invalidate the access tokens of the user.

Our issue is, if a user was connected on websiteA and websiteB and logout from websiteA, he still have an active local session on websiteB through they browser.

Basically we want the user logout of the websiteB, a bit like if you logout from google drive you will also be logout from gmail as soon as you open gmail.com

Hopefully for us, keycloak support OIDC backchannel logout

So we define that when a user logout from keycloak, a LogoutToken is sent to every app on an endpoint that we choose

let's say websiteB/backchannel-logout

So on my JEE application, the server well receive a LogoutToken on the url /backchannel-logout

This is how the logout token look FYI

{
  "iat": 1654177246,
  "jti": "66265511-a5fc-4f60-b5b7-65bea0e1a9e2",
  "iss": "https://mykeycloakserver.com/auth/realms/myRealm",
  "aud": "websiteB",
  "sub": "18e56c69-a90d-4f32-b76a-c9166def54d0",
  "typ": "Logout",
  "sid": "5bca2f13-f7a6-4b41-bdfc-1f7a89264149",
  "events": {
    "http://schemas.openid.net/event/backchannel-logout": {},
    "revoke_offline_access": true
  }
}

At this point I have a logout request from my SSO provider keycloak, containing the sub of the user so her unique ID and I can know the user I want to logout.

But basically I just receive an HttpRequest containing a logout_token from keycloak

String logoutToken = request.getParameter("logout_token");

Then I transform it to a JWT token object and I can read it.

But I'm completely out of any user session at this point request.getSession() doesn't return me at all the session that the user have open in it's browser, and I don't have any access token to use there was invalidate by the logout, I just have this logout token.


So all the speech above is to explain what I'm doing. But the real question could be.

How from a request not related to a browser Session could I found this session and invalidate it ?

Even if we forgout the SSO context and the LogoutToken, if as an admin I want an admin logout endpoint that accept a userId value and on this endpoint I want to kill any session of this user but I'm not this user (I'm the admin) how could I do it ?

The project is not using spring, we are using a platform called XWiki,I think it's just JEE with javax.servlet-api and keycloak adapter.

import javax.servlet.http.HttpServletRequest;
import org.keycloak.KeycloakSecurityContext;

Upvotes: 5

Views: 2161

Answers (1)

Sanjay Prajapati
Sanjay Prajapati

Reputation: 834

What worked for me was to use front-channel logout instead back-channel. I also wanted the session details to clear that out once the user logs out from App-A. In back-channel logout you will not receive the session details.

Note that, the front-channel logout URL has a GET method.

Upvotes: 0

Related Questions