OWIN SignOut doesn't remove cookie

夙愿已清 提交于 2021-02-07 11:16:30

问题


I am using the OWIN middleware in an external Authentication Server that my applications authenticate to using OAuth Authorisation Code Grant flow.

I can redirect to the Authentication Server, authenticate against an external provider (Google) and redirect back to my client application with a logged in user and Application Cookie set just fine, however when I try to sign out the cookie remains after I call the AuthenticationManager.SignOut method.

My cookie options in Startup.Auth.cs are:

var cookieOptions = new CookieAuthenticationOptions
                    {
                        Provider = cookieProvider,
                        AuthenticationType = "Application",
                        AuthenticationMode = AuthenticationMode.Passive,
                        LoginPath = new PathString("/Account/Index"),
                        LogoutPath = new PathString("/Account/Logout"),
                        SlidingExpiration = true,
                        ExpireTimeSpan = TimeSpan.FromMinutes(30),
                    };
app.UseCookieAuthentication(cookieOptions);
app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ExternalCookie);
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

My login method:

var loginInfo = await AuthManager.GetExternalLoginInfoAsync();
SignInManager.ExternalSignInAsync(loginInfo, true);
var identity = AuthManager.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie).Result.Identity;

if (identity != null)
{
    AuthManager.SignIn(
                  new AuthenticationProperties {IsPersistent = true},
                  new ClaimsIdentity(identity.Claims, "Application", identity.NameClaimType, identity.RoleClaimType));

        var ticket = AuthManager.AuthenticateAsync("Application").Result;
        var identity = ticket != null ? ticket.Identity : null;
        if (identity == null)
        {
            AuthManager.Challenge("Application");
            return new HttpUnauthorizedResult();
        }

        identity = new ClaimsIdentity(identity.Claims, "Bearer", identity.NameClaimType, identity.RoleClaimType);
        AuthManager.SignIn(identity);
}

return Redirect(Request.QueryString["ReturnUrl"]);

Sign Out method:

var authTypeNames = new List<string>();
authTypeNames.Add("Google");
authTypeNames.Add("Application");
authTypeNames.Add("Bearer");
authTypeNames.Add(DefaultAuthenticationTypes.ExternalCookie);

Request.GetOwinContext().Authentication.SignOut(authTypeNames.ToArray());

I have looked at other questions like: OWIN authentication, expire current token and remove cookie and OWIN - Authentication.SignOut() doesn't remove cookies

with no luck. I'm aware I could manually delete the cookie by setting a negative expiry date, but I'd prefer to use in built method if possible.

How do I get the Application Cookie to be removed when I Sign Out?


回答1:


In order for the SignOut method to flag the authentication ticket (cookie) for removal from the client, the AuthenticationType parameter you pass into the SignOut method and value on the cookie must match exactly. If you want to remove more than one authentication ticket from the client then you'll have to match ALL of those AuthenticationTypes and pass those as a string[] to the SignOut method.

The AuthenticationType of an authentication ticket usually prefixed with the name of the host web container (i.e. something like ".AspNet.") followed by whatever you bootstrapped your OWIN CookieAuthentication settings with.

It looks like you set your AuthenticationType string value to "Application" in Startup.Auth.cs. Try simply calling:

Request.GetOwinContext().Authentication.SignOut("Application");

If that's not working for you, I would debug your application and take a look at the specific AuthenticationType on the identity for each type of authenticated user your application allows, note the value of the AuthenticationType for each one and try including them all in a string[] in your SignOut call.




回答2:


From an other StackOverFlow answer which worked for me: OWIN - Authentication.SignOut() doesn't seem to remove the cookie

Use only one of these:

Request.GetOwinContext().Authentication.SignOut();
Request.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);
HttpContext.Current.GetOwinContext().Authentication.SignOut(Microsoft.AspNet.Identity.DefaultAuthenticationTypes.ApplicationCookie);

https://dzone.com/articles/catching-systemwebowin-cookie

I would assume the second one would work for you, but it looks like that's what you're doing. Can you test that on its own? Comment out your array and confirm that that works or doesn't.

To be honest, I don't know enough about OWIN to know about the Passive Authentication mode, however.




回答3:


 AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
 FormsAuthentication.SignOut();
 Session.Abandon();



回答4:


I worked on this for days. Here is what finally worked for me. First thing I do is clear the token cache. Next, I create an array of Auth Application Types. I added these 4. You can add more, if you are using them. To my knowledge, I'm only using Cookies and OpenIdConnect, but I added Bearer and Application to be safe. The final step is to clear all remaining Cookies, if any, and any remaining Sessions, if any. Again, I worked on this for days. It was so frustrating. I'm currently using 4.0.1 of these packages.

Install-Package Microsoft.Owin.Security.OpenIdConnect
Install-Package Microsoft.Owin.Security.Cookies
Install-Package Microsoft.Owin.Host.SystemWeb

public ActionResult SignOut()
        {
            
            if (Request.IsAuthenticated)
            {
                string userId = ClaimsPrincipal.Current.FindFirst(ClaimTypes.NameIdentifier).Value;

                if (!string.IsNullOrEmpty(userId))
                {
                    // Get the user's token cache and clear it
                    SessionTokenCache tokenCache = new SessionTokenCache(userId, HttpContext);

                    string sessionID = HttpContext.Session.SessionID;

                    tokenCache.Clear(sessionID);
                }
            }

            var authTypeNames = new List<string>();
            authTypeNames.Add("Cookies");
            authTypeNames.Add("Application");
            authTypeNames.Add("Bearer");
            authTypeNames.Add("OpenIdConnect");

            // Send a sign-out request. 
            HttpContext.GetOwinContext().Authentication.SignOut(authTypeNames.ToArray());

            Request.Cookies.Clear();
            Session.RemoveAll();

            return RedirectToAction("Index", "Home");

        }



回答5:


If you have any master page then please add the below tag. May be this would be helpful.

<meta http-equiv="Cache-control" content="no-cache" />


来源:https://stackoverflow.com/questions/34734082/owin-signout-doesnt-remove-cookie

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!