将 [Authorize] 属性隐式应用于所有 Web API 控制器

Posted

技术标签:

【中文标题】将 [Authorize] 属性隐式应用于所有 Web API 控制器【英文标题】:Apply [Authorize] attribute implicitly to all Web API controllers 【发布时间】:2014-03-21 22:20:45 【问题描述】:

我的应用程序设置为必须使用 Web API 中的授权属性“授权”除登录之外的所有请求。例如

 [Authorize]
 [HttpGet, Route("api/account/profile")]
 public ApplicationUser Profile()
 
       return userModel;
 

只有登录不需要授权,因为那是你获得令牌的地方;)

[AllowAnonymous]
[HttpPost, Route("api/account/login")]
public async Task<IHttpActionResult> Login(LoginViewModel model)

   ....

不必将[Authorize] 属性添加到我的所有路线,有没有办法全局设置它?

【问题讨论】:

【参考方案1】:

你有两个选择

    通过使用授权属性装饰您的控制器来实现控制器级别。

    [Authorize]
    [RoutePrefix("api/account")]
    public class AccountController : ApiController
    
    

    您也可以将其设置为全局级别,在 WebApiConfig.cs 文件的Register 方法中

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

【讨论】:

我还建议将它放在 #if !DEBUG #endif 块中,这样可以在不需要授权的情况下简化调试。 我这样做了,但现在我得到 ALWAYS 401,确定我遗漏了什么……我还需要添加什么? 旁注:.net core api 的最新版本,需要为 AuthorizeAttribute 添加 Policy,正如 Matt Frear 在下面回答的那样。【参考方案2】:

您可以将AuthorizeAttribute 设置为WebApiConfig 文件,如下所示:

public static void Register(HttpConfiguration config)

  config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/controller/id",
    defaults: new  id = RouteParameter.Optional 
  );
  config.Filters.Add(new AuthorizeAttribute());

现在,来自 Web Api 控制器的所有方法都需要授权。如果你想移除一个方法的这个授权要求,你需要像在 Login 操作方法中一样添加属性[AllowAnonymous]

【讨论】:

【参考方案3】:

在 ASP.NET Core Web API 中是这样的:

public void ConfigureServices(IServiceCollection services)

    services.AddControllers(o =>
    
        var policy = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser()
            .Build();

        o.Filters.Add(new AuthorizeFilter(policy));
    );

来源:https://joonasw.net/view/apply-authz-by-default

【讨论】:

【参考方案4】:

从 ASP.NET Core 3.0 开始,有一种新方法可以通过使用 Endpoint Routing 中间件在不使用过滤器的情况下执行此操作,请参阅:https://docs.microsoft.com/en-gb/aspnet/core/migration/22-to-30?view=aspnetcore-5.0&tabs=visual-studio#authorization

如果还没有,您需要添加以下内容:

services.UseAuthentication(); // with authentication scheme
app.UseAuthentication();
app.UseAuthorization(); // this is enough, because DefaultPolicy is to require authentication

到端点中间件:

endpoints.MapControllers().RequireAuthorization();

JWT 认证方案示例:

public void ConfigureServices(IServiceCollection services)

    services.AddControllers();
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
    
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters()
        
            ValidateIssuer = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidateAudience = false,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
         ;

    );

   

public void Configure(IApplicationBuilder app)

    app.UseRouting();
    
    app.UseAuthentication();
    
    app.UseAuthorization();
    
    app.UseEndpoints(endpoints =>
    
        endpoints.MapControllers().RequireAuthorization();
    );

您仍然可以在控制器或操作上使用[AllowAnonymous] 允许匿名访问(例如,用于用户登录)。

【讨论】:

【参考方案5】:

我只是想在您使用的其他答案中添加一些内容

 filters.Add(container.Resolve<AuthorizeAttribute>());

如果需要,您还可以将所有依赖项注入到您的属性中

【讨论】:

以上是关于将 [Authorize] 属性隐式应用于所有 Web API 控制器的主要内容,如果未能解决你的问题,请参考以下文章

如何创建不依赖于 ASP.NET Core 声明的自定义 Authorize 属性?

在客户端 Blazor 应用程序的页面中使用 [Authorize] 属性时的授权问题

如何将枚举作为字符串参数传递给 Authorize 属性?

如何调试 [Authorize] 属性中的问题

有没有办法将 Authorize 属性与没有身份验证标头的请求一起使用?

使用 .NET Core 6 中的 [Authorize] 属性重定向到自定义登录页面