将 [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] 属性时的授权问题