To single sign out or not to?

When building a Line Of Business (LOB) application, you are usually better off with implementing the customer’s current Identity Provider (IdP) which could be ADFS, Azure AD or some others. The benefits are clear – users use a single account for all the services, authenticate through a central point, can be more protected by conditional access policies and as a great benefit, you can leverage the existing data through Microsoft Graph for example. So while it is obvious why to use Single Sign On in your application, a little bit less discussed topic is about Single Sign Out (SLO).

So while the benefits of using Single Sign On are obvious and there many articles about it, it way less discussed topic is Single Sign Out – the process of signing out the user from all web application which use the same IdP.

This, of course is most applicable with LOB applications, with most of the consumer applications, it would be a lot confusing – you sign in to Feedly with Facebook, then logout from Feedly – should you be signed out from Facebook as well? Or when you sign out from Facebook, should you be signed out from Feedly? Most of the users in consumer scenarios don’t expect that.

Basic single sign out

With business applications, this is different. Take Office 365 for example. When you sign out from Exchange Online (OWA), you automatically get signed out from SharePoint Online and other Office 365 related services.

Now when you are making an LOB application, it should follow the same principle – when the user signs out from the application, he should be automatically signed out from Office 365 and other 3rd party applications. Achieving single sign out from your application and Office 365 (and AAD of course) is fairly simple, you simply redirect the user to a signout URL like this (specified as end_session_endpoint in the OIDC metadata):

which signs them out from Azure AD (and delete the application cookies or session as well, so the user gets logged out from your application too) or simply call something like this from your ASP.NET code in the logout method:

This is the very basic method of single sign out – user signed out from both your application and the IdP. This however doesn’t get the user signed out from other 3rd party applications.

One of the nice examples of how SLO should be done is Visual Studio Team Services logout page, which logs you out from all possible instances:

This is achieved through something called front-channel SLO (I will write about it later).

Honorable mention for SLO implementation is SAML protocol, where for example Azure AD event implements the support as well. However, I don’t want to spend much time with SAML and we will focus on modern authentication protocols – especially OpenID Connect, because that’s where all the action’s gonna be.

OpenID Connect Options (RFCs)

OpenID Connect itself currently presents us with three options for how the single sign out can be handled: front-channel, back-channel and session managament. I will go over all of those briefly below.

Front-channel

The front-channel (RFC) is a method which you would use when you have a regular server-side backend (in PHP, ASP.NET and similar). When editing your application’s settings, you add a Logout URL which then gets embedded to the signout page of the IdP (usually by iframe). This is what happens when logging out from VSTS as well. This allows your server to delete the cookies set on client, delete the session etc.

You could for example handle it by simply calling in your controller for ending the session:

Note that you don’t sign out OpenID Connect middleware, because the IdP has already performed the signout.

It is usually called an endsession route, since it only terminates the session at the server and doesn’t redirect the user to the IdP logout.

Additionally, the request should also contain the session ID so you can make sure that the call is really valid and ment for the current user’s session.

Update (November 2017): When using ASP.NET Core OIDC middleware, you don’t have to create a custom route where you handle the Sign Out, but you can point the server to /signout-oidc path, which will get picked up by the middleware and the sign out will be handled for you (including session validation). You can take a look into the source for reference.

Back-channel

The back-channel (RFC) is quite similar like the front-channel, except it doesn’t get called by the client from the logout page of the IdP. This means, that the IdP calls your endpoint and provides it with a JWT which you then validate and from the information provided, you invalidate the specified session.

Session managament

Last but not least is the session management (RFC). This was designed to be mostly used with Single Page Applications hence it uses JavaScript to validate the current session. You simply it the from the OIDC metadata. Inside the iframe a check is performed against user’s session at the IdP and if it has changed (user logged out, logged in as another user, …), your code gets notified back by postMessage, they should be sent to the end_session_endpoint from the metadata as well. This should be done periodically (the RFC sample has interval of 3 seconds). It is also worth noting, that this usually works alongside with the front-channel logout as well.

Doing this in Azure AD

The above is the explanation for what the OIDC RFCs specify, however let’s take a look at how we can leverage this with Azure Active Directory:

At the time of writing this article, the best way of handling SLO in your application is by using the session management. That means that in every single page you render on the server, you include a tiny bit of JavaScript code and an iframe which in case of change redirect the user to the end session endpoint of your application.

While you can specify a Logout URL for your application, it doesn’t seem to have any effect on the sign out process – it doesn’t get triggered by either front-channel or back-channel calls. However, when you look into the code of the Azure AD logout page (CLICKING THIS WILL LOG YOU OUT: https://login.microsoftonline.com/common/oauth2/logout), there is some JavaScript code which suggests support of the front-channel coming to us (no idea when tho). Also note the highlighted line which sets the constant result to success :).

So this is it, many happy single sign outs! Also if you are looking into implementing the SLO to your ASP.NET application, the official sample might come in handy.

Leave a Reply