Single Sign-out¶
Note
The content described in this article is deprecated if using the User Web Component. See User Session Avatar for more information. Recommended approach for web apps that manages the access token (like SPAs).
In this article, we will cover Single Sign Out and also Single Session Management; as both concepts are related.
In this section, the integration of single sign-out are explained. For clarity reasons, all samples will be based on Workflow application. Also, we will cover the session timeout management. All applications must be in the same domain (ie *.office,.sbs) in order to being able to integrate the SSO.
Overview¶
Signing out is as simple as removing the authentication cookie, but for doing a complete federated sign-out, we must consider signing the user out of the client applications as well.
In our scenario, we need to cover two different use cases:
- Server side integration: Integrate single sign-in & single sign-out between applications using the back channel, for server side applications (as MVC applications).
- Client side integration: Improve user experience to support manual sign-out and detect sign-out events.
Server side integration¶
app.UseSequelSecurity(securitySettings)
.UseSecurityCookie()
.UseOidcAuthentication(
WorkflowAppSettings.SecurityConfigurationClientId /*wf.conf*/,
context => context.Request.Path.Value.ToLower().Contains("/api/")
&& !context.Request.Path.Value.ToLower().Contains("/publicapi/"),
mainAppRegistration);
Sequel.Workflow.Security.AuthenticationAppInitializer.cs
In this sample, we are configuring Workflow application.
Configuring Uris¶
Single sign-in: RedirectUri¶
For defining the single sign-in we had to define the RedirectUri
, this was configured in the security database; at RedirectUri
field from [authentication].[ClientRedirect]
table. Also, same settings must be defined in the web.config (must be exactly the same value without slash character at the end) of each application and used as redirect URI after a successful login.
<add key="SecuritySettings:Authentication:ClientRedirect"
value="https://POTOROOWF.office.sbs/Workflow/sign" />
This URI is used as a callback when single sign-in is initiated by a client application (like Workflow). When trying to access to a web base application and client requires authentication, the browser is redirected to an URL similar to:
https://potorooauth.office.sbs/Authentication/Login/?
returnUrl=%2FAuthentication%2Fconnect%2Fauthorize%2Fcallback%3Fclient_id%3Dwf.conf
%26redirect_uri%3Dhttps%253A%252F%252FPOTOROOWF.office.sbs%252FWorkflow%252Fsign
%26response_mode%3Dform_post
%26response_type%3Dcode%2520id_token
%26scope%3Dopenid%2520profile%2520offline_access%2520sec.authorization%2520sec.api
%26state%3DOpenIdConnect.AuthenticationProperties%253.....
Containing the client_id
and redirect_uri
that must match with the setting in the security service.
Single sign-out: PostLogoutRedirectUri¶
Similar to the RedirectUri
used by sign-in, we need a PostLogoutRedirectUri
. This URI will be used for redirecting to the client application again, in case the user performs a new login from Login Screen in security after signing-out from a client. In this scenario, we will expect the user will be redirected to the same client application.
PostLogoutRedirectUri
must be configured in the security server, at PostLogoutRedirectUri
field from [authentication].[PostLogoutRedirectUri ]
. Also, the same value must be stored in the web.config file (must be exactly the same value without slash character at the end):
<add key="SecuritySettings:Authentication:ClientPostLogoutRedirectUri"
value="https://POTOROOWF.office.sbs/Workflow" />
Logout from a client application¶
Once defined the integration of the single sign-in and sign-out in security service; we need to integrate the sign-out within the application. As mentioned before, sign-out is based on removing cookies and forcing a redirection to the Authentication server; and this is done by below code that we are placing in Logout action at SignController
. In our sample in Workflow:
using Sequel.Workflow.Web.Filters;
using System.Web;
using System.Web.Mvc;
namespace Sequel.Workflow.Web.Controllers
{
public class SignController : Controller
{
[SecurableNotRequired]
public ActionResult Index()
{
return RedirectToAction("Index", "Home");
}
[SecurableNotRequired]
[AllowAnonymous]
public ActionResult Logout()
{
var client = AppConfiguration.WorkflowAppSettings.Instance.SecuritySettings.AuthenticationSettings.ClientsSettings[AppConfiguration.WorkflowAppSettings.SecurityConfigurationClientId];
if (Request.IsAuthenticated)
{
Request.GetOwinContext().Authentication.SignOut(
new Microsoft.Owin.Security.AuthenticationProperties()
{
RedirectUri = client.ExternalSettings.PostLogoutRedirectUri
});
}
return Redirect(client.ExternalSettings.PostLogoutRedirectUri);
}
}
}
Client side integration¶
At the front-end side, we need to offer below functionalities:
- Perform a sign-out.
- Detect a single sign-out event triggered by a different application.
- Auto sign-out for inactive sessions.
Use the component!
There is a component that has all this functionallity implemented for SPAs and similar web apps. Checkout User Session Avatar.
Perform a sign-out¶
As a user of a client application (in this case Workflow), I will be able to click on a logout button and trigger a sign-out.
This sign-out button calls to Sign/Logout
action, previously defined.
Single Session Management¶
In this section we will describe how single session is managed in terms of syncing single sign outs and also for detecting inactive sessions (across all application, not just in a single window/application).
Detect a single sign-out event¶
For reacting to a single sign-out event in the browser, we need to check the existence of SQ.sso
cookie; if that cookie is not found we will call to the logout endpoint. This logic was previously implemented in the layout.html; this is no longer required as is managed as part of the CookieSsso
service described in the next section. Current implementation checks every 5 seconds if the cookie exists.
Detect inactive sessions¶
When a user is inactive for a long period (SessionTimeout
setting) a pop-up is displayed to the user for confirming if is still working and wants to stay connected; in case, there are no confirmation from the user after a period of time (TimeoutWarningInMins
) a sign-out is forced.
The implementation has been redesigned to detect, not just activity in a single window browser; also to detect activity associated with the current session in any windows running an application logged in the same session. The solution described above is based on the idea that all active sessions have the same associated SQ.sso
cookie. We have added a timestamp to this cookie that is refreshed in every single call to the server side. When the timestamps remains the same for more than SessionTimeout
the session is considered inactive and a single sign out is forced.
For implementing this functionality we need to apply some changes to the existing implementation (changes are using Workflow as reference):
Server side changes¶
'Sequel.Security.Integration' NuGet package in version 1.0.19088.1 is required for generating the new SQ.sso
cookie with the timestamp.
Also, a new enpoint in the SignController is required in order to force a manual refresh of this cookie:
public class SignController : Controller
{
.
.
.
[SecurableNotRequired]
public void RenewSsoCookie() { }
}
Summary of steps for upgrading from previos versions¶
- Upgrade Sequel.Security.Integration to at least version 1.0.19088.1
- Add new action in controller: SignController => RenewSsoCookie
- Add CookieSso and Cookie to project. Register in application
- Remove all related code in frontend and use the User Session Avatar