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

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

问题描述

作为一个测试,我使用Visual Studio 2013中的最新模板创建了一个新的Asp.Net MVC5应用程序。我在Global.asax.cs中添加了以下方法:

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

当我启动应用程序并使用注册用户的凭据,返回给客户端的Cookie为:





请注意,我添加的自定义cookie显示在响应中没有设置Cookie的时间为Application_PreSendRequestHeaders ) 叫做。尽管如此,所有的Auth cookie到达客户端。我的理解是Application_PreSendRequestHeaders()是我们可以钩到修改cookie的最后阶段。



(如果你有兴趣,我的动机是所有这一切是:我' m尝试将auth cookie的域修改为.abc.com,其中abc.com是请求URI中主机的最后两个部分。我想这样做在全局Owin配置( IAppBuilder )的上下文中设置CookieDomain是不够的,因为请求主机在我们的调试/暂存/生产环境,我们经常将生产代码部署到Azure staging首先进行测试,然后进行VIP交换)。



(请注意,我知道像这一个,但它不' t说明Cookie实际设置的位置)



编辑:



我正在研究错误的管道。 Owin有自己的管道,所以我找到了这篇文章描述我们如何可以钩住它。中提琴...有饼干。



编辑2:

p>最后决定调查Katana源代码,发现我需要做的所有我需要做的,以获取我的cookie域设置是以下代码在我的CookieAuthenticationProvider

  OnResponseSignIn = context => 
{
//仅限示例!
context.CookieOptions.Domain = context.Request.Uri.Host;
},
OnResponseSignOut = context =>
{
//仅限示例!
context.CookieOptions.Domain = context.Request.Uri.Host;
}

编辑3:



为我的案例更干净的解决方案只是使用自定义Cookie管理器,它设置基于当前请求URI的cookie域:

  ///< summary> 
///这个类只是将cookie域附加到通常的auth cookie
///< / 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上下文,字符串键,字符串值,CookieOptions选项)
{
//简化(使用上下文参数获取所需的请求信息)
options.Domain =.domainBasedOnRequestInContext.com;
_chunkingCookieManager.AppendResponseCookie(context,key,value,options);
}

public void DeleteCookie(IOwinContext context,string key,CookieOptions options)
{
//简化(使用context参数获取所需的请求信息)
options.Domain =.domainBasedOnRequestInContext.com;
_chunkingCookieManager.DeleteCookie(context,key,options);
}
}

...然后在Cookie Auth Owin设置中的选项:

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

希望帮助某人遇到同样的问题。



p>建议的解决方案:使用自定义Cookie管理器。

  ///< summary> 
///这个类只是将cookie域附加到通常的auth cookie
///< / 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上下文,字符串键,字符串值,CookieOptions选项)
{
//简化(使用上下文参数获取所需的请求信息)
options.Domain =.domainBasedOnRequestInContext.com;
_chunkingCookieManager.AppendResponseCookie(context,key,value,options);
}

public void DeleteCookie(IOwinContext context,string key,CookieOptions options)
{
//简化(使用context参数获取所需的请求信息)
options.Domain =.domainBasedOnRequestInContext.com;
_chunkingCookieManager.DeleteCookie(context,key,options);
}
}

...然后可以在Cookie中设置Owin设置中的Auth选项:

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


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

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:

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?

(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)

EDIT:

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.

EDIT 2:

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

Edit 3:

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

...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.

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

...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天全站免登陆