2015-03-31 60 views
3

我需要在WebAPI管道的身份驗證步驟中讀取/寫入cookie。我爲此創建了一個自定義過濾器。在HttpAuthenticationContext中爲IAuthenticationFilter設置Cookie值

爲了遵守自託管概念,將訪問和寫入客戶端的安全方法是什麼? Rick Strahl評論說,如果我們使用HttpContext.Current.Response.Cookies.Add(),並且我的應用程序是自託管的,則上下文可能不會存在。

那麼如何使用HttpAuthenticationContext將客戶端cookie寫入客戶端,並且仍然是自主主機安全的?

回答

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軟件包的人),最有效的方法是在術語'version =「xxx」targetFramework =「net45的.config文件上進行全局搜索/替換如果你的老闆或你的媽媽不會讓你升級nuget軟件包,在最壞的情況下,如果你的老闆或你的媽媽不會讓你升級nuget軟件包,你總是可以採取反叛的態度和反編譯包含的addCookie的代碼,它看起來是這樣的:

    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()); 
           } 
          } 
         } 
        } 
    
    • 你到底覺得有點愚蠢的開支SO 3 M UCH時間尋找一個擴展方法,當你意識到,在加入webapi2一個cookie在一行代碼做簡單:

headers.TryAddWithoutValidation(「設置Cookie」,新CookieHeaderValue( 「核心價值」)); //標頭爲HttpResponseHeaders

+0

嗨@uzul,我做我的'Headers'對象沒有'AddCookies'。有不同的命名空間嗎?我的'HttpAuthenticationContext'是'System.Web.Http.Filters'命名空間的一部分。 – FrankO 2015-04-07 14:48:51

+0

Hi @FrankO的確,AddCookies是一個擴展方法:)你只需要添加組件System.Net.Http.Formatting.dll – uzul 2015-04-08 02:34:42

+0

嗨@uzul,我無法添加它,因爲程序集已經是項目的一部分。 :)我嘗試添加命名空間,但仍然無法使其工作。我正在使用Web API2和.Net 4.5。任何其他想法? – FrankO 2015-04-08 20:32:17

1

您不能從IAuthenticationFilter.AuthenticateAsync()內訪問authContext.ActionContext.Response。那麼,其實你可以,但只能設置一個新的響應,並快速完成其餘的管道。

我有同樣的問題(在驗證成功後設置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; 
} 

參見:Set cookie from Web Api 2 IAuthenticationFilter AuthenticateAsync method