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

41

我的应用程序设置为除登录外的所有请求都必须使用 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]属性,而不必在所有路由中都添加它?

6个回答

68

你有两个选项

  1. 通过使用authorize属性为控制器添加授权级别。

    [Authorize]
    [RoutePrefix("api/account")]
    public class AccountController : ApiController
    {
    
    您还可以在WebApiConfig.cs文件的Register方法中将其设置为全局路由级别。
     config.Filters.Add(new AuthorizeAttribute());
    

6
我建议将此放入#if !DEBUG #endif块中,以便在不需要授权的情况下轻松进行调试。 - ilans
我已经做了这个,但现在我总是得到401错误,肯定是我漏掉了什么...我还需要添加什么? - Piero Alberto
1
附注:最近版本的 .net core api,需要像 Matt Frear 在下面回答的那样为 AuthorizeAttribute 添加 Policy - Balagurunathan Marimuthu

23
您可以像下面这样在 WebApiConfig 文件中设置 AuthorizeAttribute:
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控制器中的所有方法都需要授权。如果您希望删除某个方法的授权要求,则需要添加[AllowAnonymous]属性,就像在登录操作方法中一样。


12

自从ASP.NET Core 3.0以来,有一种新的方法可以使用终结点路由中间件来完成而无需使用过滤器,详见:https://learn.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] 允许匿名访问(例如用户登录)。


6
在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

该文章介绍如何通过默认授权来提高IT系统的安全性。具体而言,通过强制要求对访问权限进行显式授权,可以防止未经授权的访问,从而降低了被攻击的风险。此外,该方法还可以使系统更加容易管理和维护,并有助于确保合规性。

1
我是一名有用的助手,可以进行文本翻译。以下是需要翻译的内容:

我只是想在其他答案中补充一些东西,如果您使用

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

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


0

我使用另一种方法 - 因为我所有的ApiController类都派生自我的自定义类ControllerBase,所以我只需将我的自定义属性[RequireAuthorization]设置到这个基类中。因此,这将被继承到所有派生的控制器类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接