Admin URL not called - how to do/trigger backchannel logout correctly?

TL;DR

I want to ensure that all browser sessions notice “immediately” when one Single-Sign-On participant logs out. I’m hoping to do by having the AdminURL being called when a user logs out

But I can’t seem to trigger the AdminURL getting called when a user logs out. My guess is that I’m using frontchannel logout, where I should be using backchannel logout. Is it correct that the Admin URL is triggered only by backchannel logouts?

If so, how does one perform a backchannel logout from a webserver that has implemented Authorization Code Flow and has access, id and refresh tokens?

Or is there a tiny hello world example that demonstrates how it works?

Details

I have a user that logs in to multiple applications using different clients using Authentication Code Flow. He logs out by redirecting to

http://192.168.225.5:8181/auth/realms/$realm/protocol/openid-connect/logout?redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F%2Foauth2%2FlogoutCB

Once he does that, the other clients notice the logout indirectly after the access tokens expire and an attempt to refresh it is done with the refresh token. So the logout works - the session is cleared in KC, but AdminURL is not called even when configured. (I’ve also tried posting to that URL providing a refresh_token, client_id and client_secret - AdminURL also not called)

If instead I hit “Logout all” from the Sessions part of the KC admin console, the AdminURL is called, so it looks to me like the AdminURL is configured properly.

There sevaral mentions of this here and there. That last one was on the mailing list 4 days ago.

This post says:

The ordinary logout and the backchannel logout are two complete different things.

The ordinary logout works by redirecting the browser to the URL you mentioned in (2). The user is recognized by the browser session in Keycloak, hence a browser redirect is crucial (the redirect_uri is not even necessary to provide).

I think the deal is that there is front-channel and backchannel logout, and only backchannel logout triggers the Admin URL webhook. Is that correct? Is it also correct that /auth/realms/test/protocol/openid-connect/logout is the frontchannel logout endpoint? If so, how do trigger a backchannel logout so the AdminURL is called?

I’m using Keycloak 11.0.0, and I’ve also tried Keycloak 7.0.0. I created a “test” realm and two clients and a user, where I make the clients confidential and configure their AdminURL to be http://192.168.225.5:9998 and http://192.168.225.5:9999 respectively. These AdminURLs are called when I hit “Logout all” from the Sessions part of the KC admin console, but not when a user logs out by either redirecting to or posting to /auth/realms/$realm/protocol/openid-connect/logout

Can anybody see what am I doing wrong? Or is there a bug in KC? I think I’ve spent about 20 hours on this and I’m going crazy… :wink:

Turns out you have to include a keycloak-specific client_session_state=${sessionId} parameter when the protocol/openid-connect/token endpoint is called.

Thanks for your post, @jtheof!

Hello, I’m from the future.

Keycloak 12 was released in Dec 2020, implementing OpenID Connect Back-Channel Logout 1.0, making this issue hopefully obsolete.

Hi,

Back-channel logout functionality is available in Keycloak 12.0. Can somebody please provide guidance on how to handle back-channel logout callback from Keycloak at application. An example code would greatly help. I am new to this.
I was going through the Keycloak source and there is a REST service with path /backchannel-logout, If somebody knows what it is, please help. It is in LogoutEndpoint.java under org.keycloak.protocol.oidc.endpoints package.

@pmorch how do you include client_session_state=${sessionId} in token endpoint call ?

Would you please tell me what client_session_state stand for? Is it the one “session_state” from keycloak in the getting authentication code process? Thanks.

It doesn’t really matter what you send in the client_session_state as long as you send something. It needs to be sent as a POST parameter in the call to to the token endpoint. Whatever you send will be sent to you in the Admin URL callback, so you can put anything you like in it, e.g. the sessionID of your application, so you can delete the session.

But if the client_session_state is missing, the Admin URL is not called.

Thanks for your reply, I am using Keycloak 15, and I can successfully complete the scenario that logout one App and any other Single-Sign-On Apps will be logout, and in this scenario the Admin URL will not be called but instead the back channel URL will be called. If I click the “Logout all” button in Keycloak admin console, the Admin URL will be triggered and I can receive a LOGOUT action, there is no session id in this action, for my understanding, if the “Logout all” is triggered, all the sessions of all the App should be logout, it doesn’t need a specific session id for the Admin URL, am I right?