collective / pas.plugins.oidc

PAS plugin for OpenID Connect authentication
Other
3 stars 13 forks source link

Single Log Out implementation with Plone and Keycloak #62

Open macagua opened 4 months ago

macagua commented 4 months ago

Has anyone had the opportunity to implement Single Log Out with pas.plugins.oidc and Plone with Keycloak?

About Single Logout (SLO)

OpenID Connect Single Logout is a feature that builds on the OpenID Connect authentication protocol. It enables users to securely log out from web applications. When the user begins the logout process, the identity provider communicates with all the parties involved to get all sessions terminated without having the user to actively log out from every app or website.

NOTE: Single Logout (SLO) is the counterpart to Single Sign-On (SSO), in this implementation, both cases will be used.


How OpenID Connect Logout Works

Logout aims to invalidate an active session. Depending on the implementation, session information resides in different places:

Logout mechanisms

To address the different architectures OpenID Connect defines three logout mechanisms:

Back-Channel Logout

The OpenID Connect Back-Channel Logout 1.0 specifies a server-to-server communication for the logout request. Therefore there is no dependency on the user agent. As a result, users will get logged out from the client even in case the user agent was closed which will not work in the other specifications.

The Back-channel logout enables seamless user logout from all applications without the user being directly involved. It ensures that the user is logged out from all SSO applications even if they have logged out from only one application.

Front-Channel Logout

The OpenID Connect Front-Channel Logout 1.0 is handled through the user agent. For each client that has a session for the user from the OpenID provider and that supports the front-channel logout mechanism, an iframe is rendered. This means that logout requests of all clients are performed in parallel.

The Front-channel logout is considered more user-friendly than Back-channel logout because it provides immediate feedback to the user and ensures that they are logged out of all applications as quickly as possible. However, it requires the user’s browser to support the HTML iframes or redirects to enable communication between the applications and the IdP.

Session Management

The OpenID Connect Session Management 1.0 defines a mechanism for an OpenID client (Relying Party, RP) to monitor a user’s login status at the OpenID provider (OP, namely the Keycloak Identity Server). When the user logs out of the OpenID provider the client should terminate its session with the user as well.

The Session management can be used in addition to the two logout mechanisms. Your application actively and regularly checks the validity of the session with Mein Bildungsraum. This regular query allows your application to determine when the session has expired and automatically log out the user to ensure the security and integrity of the application.

Benefits of Single Logout

Single Logout (SLO) support with Keycloak

The SLO support is built into the Logout settings for the Keycloak client.

Backchannel Logout

This is a non-browser-based logout that uses direct backchannel communication between Keycloak and clients. Keycloak sends a HTTP POST request containing a logout token to all clients logged into Keycloak. These requests are sent to a registered backchannel logout URLs at Keycloak and are supposed to trigger a logout on the client side.

More information: https://www.keycloak.org/docs/latest/server_admin/#backchannel-logout

Backchannel logout URL

URL that will cause the client to log itself out when a logout request is sent to this realm (via end_session_endpoint). If omitted, no logout requests are sent to the client.

Backchannel logout session required

Specifies whether a session ID Claim is included in the Logout Token when the Backchannel Logout URL is used.

Backchannel logout revoke offline sessions

Specifies whether a revoke_offline_access event is included in the Logout Token when the Backchannel Logout URL is used. Keycloak will revoke offline sessions when receiving a Logout Token with this event.

More information: https://www.keycloak.org/docs/latest/server_admin/#logout-settings


Single Logout (SLO) Scenario

In a scenario of SSO deployment with a Plone website with another custom web app, the user can log in with the Plone website, so when the user tries to log in with the custom web app it detects the SSO made and logs in automatically.

When the user tries to log out from the custom web app, it sends a notification to the Kecloak instance for log out, and it closes successfully all the user sessions.

But the Plone site remains with the user's session active because it has not received any notification of the logout, to do this you need to request the URL /acl_users/oidc/logout.

NOTE: In this scenario, I prefer to use the Back-Channel Logout case for the Single Logout (SLO).


I think that we need to implement a Rest API POST endpoint to send the notification from the Keycloak server to the Plone website.

@mamico @ericof @erral @ramiroluz Any ideas or comments for this implementation?

erral commented 4 months ago

I didn't know that Single Log Out even existed, so I can't help here.

ramiroluz commented 4 months ago

Let me understand. The idea here is:

Is that correct?

For this to work, keycloak needs to send a logout for the REST API Post, correct?

There is a place where we configure this endpoint in the keycloak admin?

Could we try to just use the /acl_users/oidc/logout/ in keycloak?

macagua commented 4 months ago

Let me understand. The idea here is:

  • User is logged in keycloak sso;
  • User is logged in a web app;
  • User is logged in plone;
  • User request the logout in the web app.
  • User should be logged out in Plone.

Is that correct?

For this to work, keycloak needs to send a logout for the REST API Post, correct?

There is a place where we configure this endpoint in the keycloak admin?

Could we try to just use the /acl_users/oidc/logout/ in keycloak?

@ramiroluz Yes, from the Keycloak admin, you can define the user logout settings for the client, which requires implementing Single Logout (SLO).

To implement the get the SLO, you need to set the Client Logout settings:

Open the Keycloak Admin Console at the following link http://127.0.0.1:8180/admin

Now you can fill in the Settings -> Logout settings.

Backchannel logout URL, for this field are the following are possible values:

The Logout OIDC Browser View URL doesn't work because at the moment to fire this request, there are not any sessions to destroy, because they were previously destroyed by the notification sent by the other custom application logout request.

I am evaluating what type of request the Keycloak server sends through its client to the application for logout to determine if I can use one of the existing ones or create a Rest Api Endpoint for active logout.

ramiroluz commented 4 months ago

Got it. Using volto-authomatic + oidc I can logout using the front end only. Like http://localhost:3000/logout

mamico commented 4 months ago

@macagua, my two cents.

At the moment, all OIDC identity providers that I've integrated didn't have SLO requirements.

However, for what I know, Plone/Volto session are stored in the client/browser side (with cookies) and there is not possibility to manage/invalidate the token server side.

So, in my opinion, there are two options: work with Front-Channel SLO or rethink the Plone/Volto session management to implement a form of server-side token invalidation (maybe not trivial).

I hope I'm not wrong and that I have been helpful.