如何Owin能够在Application_EndRequest阶段之后设置Asp.Net身份验证Cookie? [英] How is Owin able to set the Asp.Net Identity authentication cookies after the Application_EndRequest stage?

查看:165
本文介绍了如何Owin能够在Application_EndRequest阶段之后设置Asp.Net身份验证Cookie?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为测试,我创建了使用在Visual Studio 2013年我加入了下面的方法来的Global.asax.cs最新范本,一个新的Asp.Net MVC5应用:

As a test, I created a fresh Asp.Net MVC5 app using the latest template in Visual Studio 2013. I added the following method to Global.asax.cs:

    protected void Application_PreSendRequestHeaders()
    {
        Response.AppendCookie(new HttpCookie("TotalNumberOfCookiesInApplication_EndRequestIs", Response.Cookies.Count + string.Empty));
    }

当我启动应用程序,并做了POST使用已注册的用户的凭据/帐号/登录,即获得返回给客户端的cookie是:

When I start the app and do a POST to /Account/Login using the credentials of a registered user, the cookies that get returned to the client are:

请注意,我已经添加的自定义的cookie表明,没有通过的时候Application_ preSendRequestHeaders()被调用的响应设置cookies。尽管如此,所有的验证饼干到达客户端。我的理解是Application_ preSendRequestHeaders()是我们可以挂钩的最后阶段进入修改饼干。是Owin中间件能后以某种方式添加饼干,还是我失去了一些东西?

Note that the custom cookie I've added shows that there are no cookies set in the response by the time Application_PreSendRequestHeaders() is called. Despite this, all the Auth cookies arrive at the client. I was of the understanding that Application_PreSendRequestHeaders() is the last stage we can "hook" into for modifying cookies. Is the Owin middleware able to somehow add cookies after that, or am I missing something?

(如果你有兴趣,我这一切的动机是:我试图修改的身份验证cookie的域名是.abc.com,其中abc.com是的在请求URI的主机的后两部分的,我想这样做是为了支持跨多个子域认证,在全球Owin配置(上下文设置CookieDomain IAppBuilder )是不够的,因为我们的调试/分期/生产环境之间请求主机的变化,我们经常做一个VIP交换)之前部署生产code到Azure的第一个分段进行测试。

(In case you're interested, my motivation for all this is: I'm trying to modify the domain of the auth cookies to be ".abc.com", where "abc.com" is the last two parts of the host in the request URI. I want to do this to support authentication across multiple subdomains. Setting the CookieDomain in the context of the global Owin configuration (IAppBuilder) isn't enough because the request host changes between our debug/staging/production environments, and we often deploy the production code to Azure staging first for testing before doing a VIP swap).

(另请注意,我知道像这个职位之一,但它并不能解释其中饼干实际设置)

(Note also that I'm aware of posts like this one, however it doesn't explain where the cookies are actually set)

编辑:

根据一个多一点的搜索,似乎我找了错误的管道。 Owin有自己的管道,所以我发现这个帖子它描述了我们如何可以挂接到它。中提琴...还有饼干。将是巨大的,如果有人可以证实,这确实是最明智的办法做到这一点。

Based on a bit more searching, it seems I'm looking into the wrong pipeline. Owin has its own pipeline, so I found this post which describes how we can hook into it. Viola...there were the cookies. Would be great if anybody could confirm that this is indeed the most sensible way to do it.

编辑2:

最后决定寻找到武士刀源$ C ​​$ c和发现,所有我需要做的就是我的cookie设置域在下列code在我CookieAuthenticationProvider

Finally decided to look into the Katana source code and found out that all I needed to do to get my cookie domains set was the following code in my 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域:

An even cleaner solution for my case was just to use a custom cookie manager, which set the cookie domain based on the current request URI:

/// <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的身份验证选项设置:

...which is then set in the Cookie Auth Options in the Owin setup:

        app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            ...
            CookieManager = new ChunkingCookieManagerWithSubdomains(), 
            ...
            }
        });

希望帮助整个同类问题的人来了。

Hope that helps somebody coming across the same kind of question.

推荐答案

由于所要求的天向,这是我在上面的原帖编辑的总结,作为一个答案。

As requested by Tieson, here's a summary of my edits in the original post above, as an answer.

建议解决方案:使用自定义cookie管理器

Suggested solution: Use a custom cookie manager.

/// <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的身份验证选项进行设置:

...which can then be set in the Cookie Auth Options in the Owin setup:

app.UseCookieAuthentication(new CookieAuthenticationOptions
        {
            ...
            CookieManager = new ChunkingCookieManagerWithSubdomains(), 
            ...
            }
        });

这篇关于如何Owin能够在Application_EndRequest阶段之后设置Asp.Net身份验证Cookie?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆