使用Web Api 2.2,我有一个自定义 IAuthenticationFilter
,用于通过自定义方案验证客户端请求 .
基本上,当客户端未经过身份验证并想要访问受保护资源时,他会在请求旁边发送 Authorization
标头: Authorization: MyCustomScheme XXXXXXX
. 然后,过滤器验证凭据,对用户进行身份验证并生成无状态身份验证令牌以进一步访问(类似于JWT) .
我想将生成的身份验证令牌存储在cookie中 . 当存在于传入请求中时,cookie将在单独的过滤器中进行本地验证(此处未显示) .
我的问题是,如果我尝试像这样设置cookie:
Task IAuthenticationFilter.AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
if (context.Request.Headers.Authorization != null &&
string.Equals(context.Request.Headers.Authorization.Scheme, "MyCustomScheme", StringComparison.OrdinalIgnoreCase))
{
// This works
CustomPrincipal principal = this.ValidateCredentials(context.Request.Headers.Authorization.Parameter);
context.Principal = principal;
// This doesn't work: context.ActionContext.Response is null
var cookie = new CookieHeaderValue("MySessionCookie", principal.AuthenticationToken) { Path = "/", HttpOnly = true };
context.ActionContext.Response.Headers.AddCookies(new CookieHeaderValue[] { cookie });
}
return Task.FromResult(0);
}
然后它失败,因为 context.ActionContext.Response
为null . 如何在 AuthenticateAsync
内为响应添加cookie?
请参阅相关内容:Setting Cookie values in HttpAuthenticationContext for IAuthenticationFilter(您可以在评论中看到人们遇到同样的问题) .
3 回答
除了
IAuthenticationFilter
之外,我还通过实现IActionFilter
来使过滤器工作 . 此方法有效,因为您可以在同一位置访问请求,响应和用户标识 . 这是我的实施:我发现这个方法非常不实用(混合接口),你绝对应该可以访问
IAuthenticationFilter.AuthenticateAsync
中的响应(通过例如异步延续回调,或者通过能够在上下文中访问动作结果(IHttpActionResult
),如ChallengeAsync
同一界面的方法) .我的要求是添加 Headers ,但应该很容易适应添加cookie .
我对此采取了不同的方法 . 我把我想添加的 Headers 添加到
context.Request.Properties
中 . 然后在ChallengeAsync
(它被调用每个请求,无论如何)通过IHttpActionResult
我检查是否存在属性,如果存在则将其添加到 Headers 中 . 像这样的东西:}
然后在
ChallengeAsync
:您可能需要实现IRequiresSessionState才能使Cookie保持不变?
见:http://www.strathweb.com/2012/11/adding-session-support-to-asp-net-web-api/