作为测试,我使用Visual Studio 2013中的最新模板创建了一个全新的Asp.Net MVC5应用程序。我将以下方法添加到Global.asax.cs中:
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, string key, CookieOptions options)
{
// Simplification (use the context parameter to get the required request info)
options.Domain = ".domainBasedOnRequestInContext.com";
_chunkingCookieManager.DeleteCookie(context, key, options);
}
}
...然后在Owin设置中的Cookie身份验证选项中设置:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
...
CookieManager = new ChunkingCookieManagerWithSubdomains(),
...
}
});
希望能帮助有人遇到同样的问题。
答案 0 :(得分:4)
根据Tieson的要求,以上是原始帖子中我的编辑摘要,作为答案。
建议的解决方案:使用自定义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, string key, CookieOptions options)
{
// Simplification (use the context parameter to get the required request info)
options.Domain = ".domainBasedOnRequestInContext.com";
_chunkingCookieManager.DeleteCookie(context, key, options);
}
}
...然后可以在Owin设置中的Cookie身份验证选项中设置:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
...
CookieManager = new ChunkingCookieManagerWithSubdomains(),
...
}
});