-
Notifications
You must be signed in to change notification settings - Fork 334
System.Web response cookie integration issues
Katana layers the OWIN abstraction on top of the System.Web object model. For instance the OWIN key owin.ResponseHeaders returns a wrapper around the HttpContext.Response.Headers collection. This works for most headers, but it does not work for the set-cookie header in some scenarios.
In OWIN, the response headers collection is the primary storage location for response cookies. System.Web however stores response cookies in a separate HttpContext.Response.Cookies collection and then writes them out to the Response.Headers collection just before sending the response. This can cause a conflict if OWIN if both approaches are used on the same request, as the Response.Cookies collection will overwrite any cookies set via the OWIN response headers. See https://web.archive.org/web/20170912171644/https://katanaproject.codeplex.com/workitem/197 for additional details.
In Katana it's common to write cookies out using the CookieAuthenticationMiddlware or the OwinResponse.Cookies API. In System.Web the SessionStateModule will set a response cookie if the user session is created on that request.
Unfortunately there is no general purpose solution to the problem. The set-cookie header from OWIN cannot be reliably re-parsed and redirected through System.Web's Response.Cookies collection. Nor can the OWIN components write directly to System.Web's Response.Cookies collection by default as this would compromise their platform independence. There are some scenario specific workarounds that can be used at the application level.
Workarounds fall into two categories. One is to re-configure System.Web so it avoids using the Response.Cookies collection and overwriting the OWIN cookies. The other approach is to re-configure the affected OWIN components so they write cookies directly to System.Web's Response.Cookies collection.
- Ensure session is established prior to authentication: The conflict between System.Web and Katana cookies is per request, so it may be possible for the application to establish the session on some request prior to the authentication flow. This should be easy to do when the user first arrives, but it may be harder to guarantee later when the session or auth cookies expire and/or need to be refreshed.
- Disable the SessionStateModule - If the application is not relying on session information, but the session module is still setting a cookie that causes the above conflict, then you may consider disabling the session state module.
- Reconfigure the CookieAuthenticationMiddleware to write directly to System.Web's cookie collection. You may also need to do this for other components that write cookies such as OpenIdConnectAuthenticationOptions.CookieManager.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
// ...
CookieManager = new SystemWebCookieManager()
});
- Katana 3.1.0+ has several implementations of ICookieManager available.
This issue has already been addressed in the next version of Katana (ASP.NET Core) where the storage of response cookies has been standardized to always store them in the response header collection.