Grant
Grant

Reputation: 11356

MVC Removing ApplicationCookie from Response

In previous MVC projects using forms authentication i was able to strip the authentication cookie from the response using an action filter with the following override.

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

I have now switched over to use OWIN based asp.net identity 2.0 and in the same way I would like to remove their version of the authentication cookie.

I have modified the filter (below) to use the new cookie name but the cookie is no longer being removed.

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

Does anyone know why?

Upvotes: 1

Views: 2246

Answers (1)

rism
rism

Reputation: 12142

The reason is that the authentication occurs in the OWIN pipeline with it's own environment dictionary, whereas your previous FormsAuthentication was using System.Web.HttpContext.

If you set a breakpoint on :

 filterContext.HttpContext.Response.Cookies

and view the variable you will see it doesn't even have a cookie named .AspNet.ApplicationCookie so you're not removing anything.

I'm not sure what you're trying to achieve by removing the cookie rather than just logging the user out but a way to do something similar would be to create an action filter as below:

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

Apply that as necessary and then do a check for the action prior to OWIN writing out the message headers by creating some OWIN middleware

  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);
            }
        }

You would attach that middleware in your startup class:

 app.Use(typeof(AuthenticationMiddleware));

Note though that while this will eat the cookie it wont log the user out but as I say I'm not sure if that is your intention anyway.

Upvotes: 6

Related Questions