protected void Application_PreSendRequestHeaders() { Response.AppendCookie(new HttpCookie("TotalNumberOfCookiesInApplication_EndRequestIs",Response.Cookies.Count + string.Empty)); }
当我启动应用程序并使用注册用户的凭据对/ Account / Login执行POST时,返回给客户端的cookie是:
请注意,我添加的自定义cookie显示,在调用Application_PreSendRequestHeaders()时,响应中没有设置cookie.尽管如此,所有Auth cookie都会到达客户端.我理解Application_PreSendRequestHeaders()是我们可以“挂钩”修改cookie的最后阶段. Owin中间件是否能够以某种方式添加cookie,或者我错过了什么?
(如果你感兴趣的话,我对这一切的动机是:我试图将auth cookie的域名修改为“.abc.com”,其中“abc.com”是主机的最后两部分在请求URI中.我想这样做是为了支持跨多个子域的身份验证.在全局Owin配置(IAppBuilder)的上下文中设置CookieDomain是不够的,因为请求主机在我们的调试/登台/生产环境之间发生变化,在进行VIP交换之前,我们经常首先将生产代码部署到Azure分段进行测试.
(另请注意,我知道像this one这样的帖子,但是它没有解释实际设置cookie的位置)
编辑:
基于更多的搜索,似乎我正在寻找错误的管道. Owin有自己的管道,所以我找到了this post,它描述了我们如何能够加入它. Viola …有饼干.如果有人能够确认这确实是最明智的做法,那将会很棒.
编辑2:
最后决定查看Katana源代码并发现我需要做的就是设置我的cookie域名是我的CookieAuthenticationProvider中的以下代码
OnResponseSignIn = context => { // Example only! context.CookieOptions.Domain = context.Request.Uri.Host; },OnResponseSignOut = context => { // Example only! context.CookieOptions.Domain = context.Request.Uri.Host; }
编辑3:
对我来说更简洁的解决方案就是使用自定义cookie管理器,它根据当前请求URI设置cookie域:
/// <summary> /// This class simply appends the cookie domain to the usual auth cookies /// </summary> public class ChunkingCookieManagerWithSubdomains : ICookieManager { private readonly ChunkingCookieManager _chunkingCookieManager; public ChunkingCookieManagerWithSubdomains() { _chunkingCookieManager = new ChunkingCookieManager(); } public string GetRequestCookie(IOwinContext context,string key) { return _chunkingCookieManager.GetRequestCookie(context,key); } public void AppendResponseCookie(IOwinContext context,string key,string value,CookieOptions options) { // Simplification (use the context parameter to get the required request info) options.Domain = ".domainBasedOnRequestInContext.com"; _chunkingCookieManager.AppendResponseCookie(context,key,value,options); } public void DeleteCookie(IOwinContext context,CookieOptions options) { // Simplification (use the context parameter to get the required request info) options.Domain = ".domainBasedOnRequestInContext.com"; _chunkingCookieManager.DeleteCookie(context,options); } }
…然后在Owin设置中的Cookie身份验证选项中设置:
app.UseCookieAuthentication(new CookieAuthenticationOptions { ... CookieManager = new ChunkingCookieManagerWithSubdomains(),... } });
希望能帮助有人遇到同样的问题.
解决方法
/// <summary> /// This class simply appends the cookie domain to the usual auth cookies /// </summary> public class ChunkingCookieManagerWithSubdomains : ICookieManager { private readonly ChunkingCookieManager _chunkingCookieManager; public ChunkingCookieManagerWithSubdomains() { _chunkingCookieManager = new ChunkingCookieManager(); } public string GetRequestCookie(IOwinContext context,options); } }
…然后可以在Owin设置中的Cookie身份验证选项中设置:
app.UseCookieAuthentication(new CookieAuthenticationOptions { ... CookieManager = new ChunkingCookieManagerWithSubdomains(),... } });