c# - 使用 AllowAnonymous 属性在 Web Api 中进行身份验证

标签 c# asp.net-web-api2

我通过继承 DelegatingHandler 实现了基于 JWT 的身份验证并将类添加为 configuration.MessageHandlers.Add(new MyDelegatingHandler()) .

实现DelegatingHandler时, 我重写 Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) .那里的逻辑很简单——我从 Authorization 中检索了一个 token 。 header ,检查其有效性。如果有效 - 我设置 Thread.CurrentPrincipalHttpContext.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 方法上也会调用此方法属性与它。这很好,因为即使该方法允许匿名,我也想设置主体。但如果提供的 token 在 Authorization 中,则此逻辑失败 header 无效。

用户使用 [AllowAnonymous] 向资源发送请求并在 Authorization 中使用无效 token header ,应该通过,因为资源允许匿名,但我的代码检查授权,发现 token 无效并发送 HttpStatusCode.Unauthorized .

修复方法是检查 // TODO: fix 在哪里是用户访问的资源是否允许匿名,只发送HttpStatusCode.Unauthorized如果不是,但我不知道如何正确执行此操作。

我该怎么做?

最佳答案

1。身份验证过滤器

使用Authentication Filters ,这是 Web API 2 引入的。它们只执行身份验证,但不会说明用户是否有权访问资源。正是您所需要的。

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());

通过这种方式,如果 token 正常,用户就可以通过身份验证。但仍然所有用户都可以访问您的 API——即使是那些使用无效 token 的用户。让我们更进一步,保护它。

2。授权属性

AuthorizeAttribute是您需要限制未经身份验证的用户对 Web API 的访问。您可以使用与上述相同的方法在全局范围内应用它:

httpConfig.Filters.Add(new AuthorizeAttribute());

没有有效 token 的人将无法通过。好的。最后一步是允许使用无效 token 的用户访问某些特定资源。

3。允许匿名属性

从现在开始,AllowAnonymousAttribute 应该可以工作了。基本上 AuthorizeAttribute 只是检查资源是否由 [AllowAnonymous] 标记,并在这种情况下跳过授权。


结论

一般来说,Web API 是针对未经身份验证的用户进行保护的,但是某些资源可以通过应用 [AllowAnonymous] 来禁用授权。我们在上面实现的 JwtAuthenticationFilter 在任何情况下都有效,因此拥有有效 token 的用户将始终通过身份验证 - 即使资源允许匿名访问。

关于c# - 使用 AllowAnonymous 属性在 Web Api 中进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50504964/

相关文章:

C# 内存类型大于 ulong

c# - XslCompiledTransform 输出为 XPathDocument

c# - PostAsJsonAsync 不使用匿名类型从 Windows 服务调用 webapi 服务,有什么明显的错误吗?

c# - .Net OData v4 客户端生成 - IDataErrorInfo

wcf - Autofac WCF - CloseChannel 在负载测试下被多次调用

c# - 如何使用 BuildManager 在 Visual Studio 2017 (MsBuild 15) 上构建 .Net Core 项目或解决方案

c# - 无法使用 PCLStorage 或 Xamarin Forms Labs 在 Android 文件系统中创建文件夹/文件

c# - Postman - 找到多个与 Web Api 中的请求匹配的操作

c# - Web API 和 HTTP 模块

c# - Angular 到 webapi httppost 调用发送用户对象,一旦它们到达用户 obj 下的 webapi 服务属性将变为 null(usrnm/pswd)