As mentioned in my previous post, OpenID Connect specifies three different forms of logout, two of which uses front channel communication. OIDC Backchannel Logout is a logout mechanism that uses backchannel communication.
As defined in Ldapwiki,
In simple terms, frontchannel communication is when requests are communicated via the User Agent (i.e. the browser, and backchannel communication is when requests are communicated using direct network links between servers.
OpenID Connect Backchannel logout is a mechanism by which Relying Party (RP) applications are logged out with logout requests communicated directly between RPs and OpenID Providers (OP) bypassing the User Agent.
This logout mechanism is much less fragile than the other methods using frontchannel communication as it does not depend on the End-User’s browser activity. This may seem like the best option for OIDC logout — however, it is not the case for every scenario as it imposes new requirements on the system.
- When an RP or the OP triggers a logout action, the OP finds all the RPs who share the same user’s session at the OP.
- The OP then generates a special JWT token called the Logout Token containing relevant claims for each RP and sends logout requests with the Logout Tokens to the logout endpoints of every RP.
- Upon receiving a Logout Token, the RP much validate the token and invalidate the session of the particular user.
The Logout Token is a JWT much like the ID Token in OpenID Connect, and is also a type of Security Event Token. It contains Claims specific to the logout action that are required by RP applications to validate and verify the logout request and trigger the logout process for a particular user.
The following Claims are used within the Logout Token:
- iss — Issuer Identifier. This is a case sensitive URL of the entity that generated the token (OP). This is a required field.
- sub — Subject Identifier. It is a unique identifier assigned by the Issuer to the Client. This field is optional.
- aud — Audience. The list of Clients to which the Logout Token is intended for. This is a required field.
- iat — Issued At Time. Time at which the token was issued. This field is required as well.
- jti — JWT ID. Unique identifier for the token. This is used to prevent Logout Token replays. This field is required.
- events — JSON object containing the member name “http://schemas. openid.net/event/backchannel-logout”. The value of the member should be an empty JSON object. This is to declare that this JWT is a Logout Token. This field is required.
- sid — Session ID. Identifier for a session of the User Agent at the RP. This field is optional.
Although the sid and sub Claims are considered optional, a Logout Token must contain either one of the Claims and may contain both. If the sid Claim is absent, the RP should log out all sessions of the End-User identified by the iss and sub Claims.
The nonce Claims should NOT be included in a Logout Token for security reasons. Logout Tokens MUST be digitally signed and MAY also be encrypted.(Refer spec)
The following is an example of a Logout Token,
How it works
The Backchannel Logout process is initiated when the OP sends an HTTP(S) POST logout request to the backchannel logout URI of the RP registered at the OP. Such a logout request would look like this:
POST /backchannel_logout HTTP/1.1
logout_token=eyJhbGci ... .eyJpc3Mi ... .T3BlbklE ...
Upon receiving a logout request , the RP should carry out necessary validation steps to ensure that the logout action is legit. The validation steps are described here. If anything goes wrong with the validation steps, the logout request should be rejected and the RP must return an HTTP 400 to the OP.
Once validation is complete and successful, the RP must locate the sessions identified by the iss and sub Claims in the Logout Token and clear any state asssociated with those sessions. Refresh Tokens without the offline_access property should be revoked as well. The mechanisms by which the RP carries out these tasks are implementation specific and are not strictly defined by the spec.
In the event an RP is also an OP serving downstream logged-in sessions, upon receiving a logout request, it should generate logout requests to all the logged-in downstream RPs as well.
Once logout is succeeded, the RP responds back to the OP with an HTTP 200 OK and the Backchannel logout process is finally finished. 😁
Pros and Cons
The Backchannel logout mechanism is more reliable than other methods as Frontchannel communication is not involved — the success of the logout request does not depend on the RP’s browser session activity.
- New requirements are imposed on the system as extra network links have to be established between servers for backchannel communication. The RP’s backchannel logout endpoint must be reachable from all OPs and cannot behind a firewall or NAT when using public OPs.
- Session state data which is stored in cookies and HTML5 storage is not available for backchannel communication. Therefore, state must be explicitly communicated between parties.
- In frontchannel methods, logging out is simply clearing cookies and HTML5 storage state. It is more complex in Backchannel logout as RPs must implement application specific methods for terminating User sessions upon receiving a logout request.