c# - 使用 AllowAnonymous 属性在 WebApi 中进行身份验证
问题描述
我通过继承DelegatingHandler
并将类添加为configuration.MessageHandlers.Add(new MyDelegatingHandler())
.
实施时DelegatingHandler
,我重写Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
。那里的逻辑很简单——我从Authorization
标头中检索一个令牌,检查它的有效性。如果它有效 - 我设置Thread.CurrentPrincipal
and HttpContext.Current.User
,否则我返回new HttpResponseMessage(HttpStatusCode.Unauthorized)
基本上它看起来像这样(非常简化):
public class TokenValidationHandler : DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var token = GetTokenFromAuthorizeHeader(request);
if (TokenIsValid(token)) {
var principal = CreatePrincipal(token);
Thread.CurrentPrincipal = principal;
HttpContext.Current.User = principal;
return base.SendAsync(request, cancellationToken);
} else {
// TODO: fix
return Task<HttpResponseMessage>.Factory.StartNew(() => new HttpResponseMessage(HttpStatusCode.Unauthorized));
}
}
}
[AllowAnonymous]
现在,即使在具有属性的WebApi 方法上也会调用此方法。这很好,因为即使该方法允许匿名,我也想设置主体。Authorization
但是,如果标头中提供的令牌无效,则此逻辑将失败。
[AllowAnonymous]
用户向标头中带有无效令牌的资源发送请求Authorization
,这应该通过,因为资源允许匿名,但我的代码检查授权,发现令牌无效并发送HttpStatusCode.Unauthorized
.
解决方法是检查// TODO: fix
用户正在访问的资源是否允许匿名,HttpStatusCode.Unauthorized
如果不是,则仅发送,但我不知道如何正确执行此操作。
我怎样才能做到这一点?
解决方案
1.身份验证过滤器
使用Web API 2 引入的Authentication Filters 。他们只执行身份验证,但没有说明用户是否有权访问资源。正是你需要的。
public class JwtAuthenticationFilter : IAuthenticationFilter
{
public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
{
var token = GetTokenFromAuthorizeHeader(context.Request);
if (TokenIsValid(token)) {
var principal = CreatePrincipal(token);
// Use context.Principal instead of Thread.CurrentPrincipal
// and HttpContext.Current.User whenever.
context.Principal = principal;
}
return Task.CompletedTask;
}
// TODO: Implement remaining IAuthencitaionFilter members.
}
全局应用此JwtAuthenticationFilter
功能以对所有请求执行身份验证:
// httpConfig is an instance of HttpConfiguration
httpConfig.Filters.Add(new JwtAuthenticationFilter());
以这种方式,如果令牌正常,则对用户进行身份验证。但仍然所有用户都可以访问您的 API——即使是那些使用无效令牌的用户。让我们更进一步,保护它。
2.授权属性
AuthorizeAttribute是限制未经身份验证的用户访问 Web API 所需要的。您可以使用与上述相同的方法在全局范围内应用它:
httpConfig.Filters.Add(new AuthorizeAttribute());
没有有效令牌的人不会通过。好的。最后一步是允许使用无效令牌的用户访问某些特定资源。
3. AllowAnonymousAttribute
从现在开始AllowAnonymousAttribute
应该工作。基本上AuthorizeAttribute
只是检查资源是否被标记[AllowAnonymous]
并在这种情况下跳过授权。
结论
通常 Web API 会受到未经身份验证的用户的保护,但某些资源可以通过应用来禁用授权[AllowAnonymous]
。JwtAuthenticationFilter
我们在任何情况下都实现了上述工作,因此具有有效令牌的用户将始终通过身份验证 - 即使资源允许匿名访问。
推荐阅读
- python - how to address all items of a list at once?
- c++ - C ++中的静态constexpr数组?
- python - 如何将文本格式更改为从 Python 拉到 Google 电子表格的表格的数字格式?
- css - 是否可以将此多色调 svg 过滤器导入程序并使用滑块微调效果?
- algorithm - 将整数的线性范围扩展到更大数组的算法
- node.js - 未捕获的类型错误:crypto.randomBytes 不是函数
- java - 无法将 int 转换为 int[] 并且未定义类型 int[]、int [] 的运算符
- python - Python:如何在 vscode 中更改脚本的执行位置?
- r - Issue running purrr::possible for error recovery inside ~ tibble
- php - 使用 curl 发布字符串和数组