MVC 从响应中删除 ApplicationCookie

MVC Removing ApplicationCookie from Response

在以前使用表单身份验证的 MVC 项目中,我能够使用具有以下覆盖的操作过滤器从响应中删除身份验证 cookie。

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
    filterContext.HttpContext.Response.Cookies.Remove(FormsAuthentication.FormsCookieName);
}

我现在已经切换到使用基于 OWIN 的 asp.net 身份 2.0,并且我想以同样的方式删除他们的身份验证 cookie 版本。

我已修改过滤器(如下)以使用新的 cookie 名称,但该 cookie 不再被删除。

public override void OnResultExecuted(ResultExecutedContext filterContext)
{
    const string authenticationCookie = CookieAuthenticationDefaults.CookiePrefix + DefaultAuthenticationTypes.ApplicationCookie;
    filterContext.HttpContext.Response.Cookies.Remove(authenticationCookie);
}

有人知道为什么吗?

原因是身份验证发生在 OWIN 管道中,它有自己的环境字典,而您之前的 FormsAuthentication 使用的是 System.Web.HttpContext。

如果在 :

上设置断点
 filterContext.HttpContext.Response.Cookies

并查看变量,您会发现它甚至没有名为 .AspNet.ApplicationCookie 的 cookie,因此您没有删除任何内容。

我不确定您要通过删除 cookie 而不仅仅是注销用户来实现什么目的,但是执行类似操作的一种方法是创建一个操作过滤器,如下所示:

public class CookieStripperAttribute : ActionFilterAttribute {
    public override void OnResultExecuted(ResultExecutedContext filterContext) {
        filterContext.HttpContext.GetOwinContext().Environment.Add("StripAspCookie", true);
    }
}

根据需要应用它,然后在 OWIN 通过创建一些 OWIN 中间件写出消息头之前检查操作

  public class AuthenticationMiddleware : OwinMiddleware
        {
            const string _authenticationCookie = CookieAuthenticationDefaults.CookiePrefix + DefaultAuthenticationTypes.ApplicationCookie;

            public AuthenticationMiddleware(OwinMiddleware next) :
                base(next) { }

            public override async Task Invoke(IOwinContext context)
            {
                var response = context.Response;
                response.OnSendingHeaders(state =>
                {
                    var resp = (OwinResponse)state;

                    if (resp.Environment.ContainsKey("StripAspCookie"))
                    {
                        resp.Cookies.Delete(_authenticationCookie);
                    }
                }, response);

                await Next.Invoke(context);
            }
        }

您可以在启动时附加该中间件 class:

 app.Use(typeof(AuthenticationMiddleware));

请注意,虽然这会吃掉 cookie,但它不会将用户注销,但正如我所说,我不确定这是否是您的意图。