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):
https://login.microsoftonline.com/<tenant or common>/oauth2/logout?post_logout_redirect_uri=<optional_uri>
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.
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.
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.
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:
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.