在HttpAuthenticationContext中为IAuthenticationFilter设置Cookie值

时间:2015-03-31 21:22:44

标签: c# cookies asp.net-web-api

我需要在WebAPI管道的身份验证步骤中读/写cookie。我为此创建了一个自定义过滤器。

为了遵守自托管概念,访问和向客户端写入cookie的安全方法是什么? Rick Strahl评论说,如果我们使用HttpContext.Current.Response.Cookies.Add(),并且我的应用程序是自托管的,则上下文可能/不会存在。

那么我如何使用HttpAuthenticationContext向客户端写一个cookie并且仍然是自托管安全的?

2 个答案:

答案 0 :(得分:2)

您无法在authContext.ActionContext.Response内访问IAuthenticationFilter.AuthenticateAsync()。嗯,实际上你可以,但只是设置一个新的响应并快捷管道的其余部分。

我遇到了同样的问题(需要在成功验证后设置Cookie)并通过IActionFilterIAuthenticationFilter之外实施async Task<HttpResponseMessage> IActionFilter.ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) { // Process the request pipeline and get the response (this causes the action to be executed) HttpResponseMessage response = await continuation(); // Here you get access to: // - The request (actionContext.Request) // - The response (response) and its cookies (response.Headers.AddCookies()) // - The principal (actionContext.ControllerContext.RequestContext.Principal) return response; } 来解决问题:

PATH

请参阅:Set cookie from Web Api 2 IAuthenticationFilter AuthenticateAsync method

答案 1 :(得分:1)

HttpAuthenticationContext authContext;
authContext.ActionContext.Response.Headers.AddCookies(/*cookies */);

<强> EDIT2

HttpAuthenticationContext authContext;
var myCookie = new CookieHeaderValue("key", "value")
authContext.ActionContext.Response.Headers.Add("Set-Cookie", myCookie.ToString());

修改

AddCookie是位于System.Net.Http.Formatting.dll(从v5.2.2.0版本开始)的扩展方法,扩展方法由位于命名空间System.Net.Http中的静态类HttpResponseHeadersExtensions声明。

  • 如果找不到扩展方法,请尝试找到HttpResponseHeadersExtensions类。

  • 如果找不到HttpResponseHeadersExtensions类,请尝试升级Web Api 2库。升级每个项目的WebApi2的所有nuget包的最有效方法(对于那些讨厌像我这样讨厌升级nuget包的人),是对term&#39; version =&#34;的.config文件进行全局搜索/替换。 XXX&#34; targetFramework =&#34; net45&#34;&#39; (其中x.x.x是旧版本,替换为&#39;版本=&#34; 5.2.2&#34; targetFramework =&#34; net45&#34;&#39;

  • 在最糟糕的情况下,如果您的老板或您的妈妈不能让您升级nuget包,您可以随时采用反叛态度并反编译包含AddCookie的代码,它看起来像这样:< / p>

        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.Net.Http.Headers;
        using System.Net.Http.Properties;
        using System.Web.Http;
        namespace System.Net.Http
        {
            /// <summary> Provides extension methods for the <see cref="T:System.Net.Http.Headers.HttpResponseHeaders" /> class. </summary>
            [EditorBrowsable(EditorBrowsableState.Never)]
            public static class HttpResponseHeadersExtensions
            {
                private const string SetCookie = "Set-Cookie";
                /// <summary> Adds cookies to a response. Each Set-Cookie header is  represented as one <see cref="T:System.Net.Http.Headers.CookieHeaderValue" /> instance. A <see cref="T:System.Net.Http.Headers.CookieHeaderValue" /> contains information about the domain, path, and other cookie information as well as one or more <see cref="T:System.Net.Http.Headers.CookieState" /> instances. Each <see cref="T:System.Net.Http.Headers.CookieState" /> instance contains a cookie name and whatever cookie state is associate with that name. The state is in the form of a  <see cref="T:System.Collections.Specialized.NameValueCollection" /> which on the wire is encoded as HTML Form URL-encoded data.  This representation allows for multiple related "cookies" to be carried within the same Cookie header while still providing separation between each cookie state. A sample Cookie header is shown below. In this example, there are two <see cref="T:System.Net.Http.Headers.CookieState" /> with names state1 and state2 respectively. Further, each cookie state contains two name/value pairs (name1/value1 and name2/value2) and (name3/value3 and name4/value4). &lt;code&gt; Set-Cookie: state1:name1=value1&amp;amp;name2=value2; state2:name3=value3&amp;amp;name4=value4; domain=domain1; path=path1; &lt;/code&gt;</summary>
                /// <param name="headers">The response headers</param>
                /// <param name="cookies">The cookie values to add to the response.</param>
                public static void AddCookies(this HttpResponseHeaders headers, IEnumerable<CookieHeaderValue> cookies)
                {
                    if (headers == null)
                    {
                        throw Error.ArgumentNull("headers");
                    }
                    if (cookies == null)
                    {
                        throw Error.ArgumentNull("cookies");
                    }
                    foreach (CookieHeaderValue current in cookies)
                    {
                        if (current == null)
                        {
                            throw Error.Argument("cookies", Resources.CookieNull, new object[0]);
                        }
                        headers.TryAddWithoutValidation("Set-Cookie", current.ToString());
                    }
                }
            }
        }
    
    • 最后,当你意识到在webapi2中添加一个cookie只是在一行代码中完成时,你会感到有点愚蠢地花费这么多时间寻找扩展方法:
  

headers.TryAddWithoutValidation(&#34; Set-Cookie&#34;,new CookieHeaderValue(&#34; key&#34;,&#34; value&#34;)); //其中headers是HttpResponseHeaders