Search code examples
c#asp.net-mvcsingle-sign-onopenid-connectidp

Microsoft SSO OpenID - Force a signout


Currently upgrading a legacy MVC.NET v3 application to v5 while changing over from Forms Authentication to Microsoft's SSO solution. The requirement we would like to carry over is to force a logout if the user is idle for 30 minutes much like a banking application does due to the confidential information displayed within the application. We've implemented this successfully in the legacy application but I'm having trouble with the signout mechanism.

public void SignOut()
{
    HttpContext.GetOwinContext().Authentication.SignOut(
            OpenIdConnectAuthenticationDefaults.AuthenticationType,
            CookieAuthenticationDefaults.AuthenticationType);
}

Without changing a thing when a user clicks the signout button - it'll redirect them to Microsoft's account selector to choose which account to log out - even if there's only one choice. But if the user clicks the back button then they are back in the application which lets an authorized user see confidential information. I need to force a logout on the current account to prevent that but I'm not able to figure out how.

I tried:

  1. Clearing cookies. Failed because if the bad actor clicks login again the current session remembers him and automatically logs them back in.
  2. Overwriting the HttpContext.User - looks like it works. But again clicking on login will automatically refresh the old session because the Token Provider remembers the state.

How do I accomplish this?

Thanks,


Solution

  • I found this link to allow session variables with OWIN: Can OWIN middleware use the http session?

    You'll need to review this link to allow system web cookies working with OWIN: ASP.NET_SessionId + OWIN Cookies do not send to browser

    I created another method that signs the user out and creates a session variable.

    public void ForceSignOut()
    {
        SignOut();
    
        HttpContext.Session.Add("IsSignoutRequested", true);
    }
    

    If the user clicks the back button and comes back to the application, I force redirect them back into a challenge.

    In my startup class I have set the PostLogoutRedirectUri which lets me create another method on a successful logout which abandons the session.

    public ActionResult CompleteSignOut()
    {
        Session.Abandon();
        Request.GetOwinContext().Authentication.SignOut();
        Request.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
        this.HttpContext.GetOwinContext().Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
    
        return new RedirectToRouteResult(new RouteValueDictionary(new
        {
            controller = "User",
            action = "Index"
        }));
    }