我需要在WebAPI管道的身份验证步骤中读/写cookie。我为此创建了一个自定义过滤器。
为了遵守自托管概念,访问和向客户端写入cookie的安全方法是什么? Rick Strahl评论说,如果我们使用HttpContext.Current.Response.Cookies.Add()
,并且我的应用程序是自托管的,则上下文可能/不会存在。
那么我如何使用HttpAuthenticationContext
向客户端写一个cookie并且仍然是自托管安全的?
答案 0 :(得分:2)
您无法在authContext.ActionContext.Response
内访问IAuthenticationFilter.AuthenticateAsync()
。嗯,实际上你可以,但只是设置一个新的响应并快捷管道的其余部分。
我遇到了同样的问题(需要在成功验证后设置Cookie)并通过IActionFilter
除IAuthenticationFilter
之外实施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). <code> Set-Cookie: state1:name1=value1&amp;name2=value2; state2:name3=value3&amp;name4=value4; domain=domain1; path=path1; </code></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());
}
}
}
}
headers.TryAddWithoutValidation(&#34; Set-Cookie&#34;,new CookieHeaderValue(&#34; key&#34;,&#34; value&#34;)); //其中headers是HttpResponseHeaders