以编程方式保护 ASP controllers/methods
Secure ASP controllers/methods programmatically
我在 API 之后,它允许从 API 应用 [Authorize]
属性,而不是将它放在控制器的 class/method.
上
考虑来自依赖 nuget 包的第三方控制器 类,我想将它们托管在我的应用程序中并为它们实现安全性。
我知道我可以使用
app.UseEndpoints(endpoints => { endpoints.MapControllers().RequireAuthorization(new AuthorizeAttribute("policy")); });
但这将配置 ALL 控制器和方法以受 policy
保护,我需要根据 class/method 进行控制。
使用
手动映射
endpoints.MapPut("***").RequireAuthorization(new AuthorizeAttribute("someOtherPolicy"))
也不是一个选项,因为映射已经在导入的控制器上使用 [Microsoft.AspNetCore.Mvc.HttpPost, Microsoft.AspNetCore.Mvc.Route("api/someRoute")]
属性定义。
请指教
如果您可以确定应在哪个端点应用特定的授权策略,您可以尝试以下操作:
public class MyAuthorizationFilter: AuthorizeAttribute, IAsyncAuthorizationFilter
{
public MyAuthorizationFilter() : base()
{
//this.AuthenticationSchemes = "";
//this.Policy = "";
//this.Roles = "";
}
public Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
context.Result = new OkObjectResult("my custom policy was checked");
return Task.CompletedTask;
}
}
public static class DynamicAuthorizationPolicies
{
public static void RegisterMyFilters(this IServiceProvider serviceProvider)
{
var allEndpoints = serviceProvider
.GetService<IActionDescriptorCollectionProvider>()
?.ActionDescriptors
?.Items;
if (allEndpoints is null)
{
return;
}
foreach (var endpoint in allEndpoints)
{
// If you debug hier you will see that you can register
// differnt filters or attribute in different collections
// for the endpoint
if (/*endpoint match some requirement*/true)
{
var authorizeFilter = serviceProvider.GetService<MyAuthorizationFilter>();
var descriptor = new FilterDescriptor(authorizeFilter, FilterScope.Action);
endpoint.FilterDescriptors.Add(descriptor);
}
}
}
}
... 这是用法:
public void ConfigureServices(IServiceCollection services)
{
// services.Add...
services.AddTransient<MyAuthorizationFilter>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// app.Use....
app.ApplicationServices.RegisterMyFilters();
}
我在 API 之后,它允许从 API 应用 [Authorize]
属性,而不是将它放在控制器的 class/method.
考虑来自依赖 nuget 包的第三方控制器 类,我想将它们托管在我的应用程序中并为它们实现安全性。 我知道我可以使用
app.UseEndpoints(endpoints => { endpoints.MapControllers().RequireAuthorization(new AuthorizeAttribute("policy")); });
但这将配置 ALL 控制器和方法以受 policy
保护,我需要根据 class/method 进行控制。
使用
endpoints.MapPut("***").RequireAuthorization(new AuthorizeAttribute("someOtherPolicy"))
也不是一个选项,因为映射已经在导入的控制器上使用 [Microsoft.AspNetCore.Mvc.HttpPost, Microsoft.AspNetCore.Mvc.Route("api/someRoute")]
属性定义。
请指教
如果您可以确定应在哪个端点应用特定的授权策略,您可以尝试以下操作:
public class MyAuthorizationFilter: AuthorizeAttribute, IAsyncAuthorizationFilter
{
public MyAuthorizationFilter() : base()
{
//this.AuthenticationSchemes = "";
//this.Policy = "";
//this.Roles = "";
}
public Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
context.Result = new OkObjectResult("my custom policy was checked");
return Task.CompletedTask;
}
}
public static class DynamicAuthorizationPolicies
{
public static void RegisterMyFilters(this IServiceProvider serviceProvider)
{
var allEndpoints = serviceProvider
.GetService<IActionDescriptorCollectionProvider>()
?.ActionDescriptors
?.Items;
if (allEndpoints is null)
{
return;
}
foreach (var endpoint in allEndpoints)
{
// If you debug hier you will see that you can register
// differnt filters or attribute in different collections
// for the endpoint
if (/*endpoint match some requirement*/true)
{
var authorizeFilter = serviceProvider.GetService<MyAuthorizationFilter>();
var descriptor = new FilterDescriptor(authorizeFilter, FilterScope.Action);
endpoint.FilterDescriptors.Add(descriptor);
}
}
}
}
... 这是用法:
public void ConfigureServices(IServiceCollection services)
{
// services.Add...
services.AddTransient<MyAuthorizationFilter>();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// app.Use....
app.ApplicationServices.RegisterMyFilters();
}