Я просто хочу спросить, могу ли я отфильтровать роли и разрешить это на основе глагола http, например, если роль отправителя - admin, он может получить доступ ко всем методам, и если роль поддерживается Он мог получить доступ только к методам Get.
Конечно. Во-первых, вам нужно создать правила:
public class GlobalVerbRoleRequirement: IAuthorizationRequirement
{
public bool IsAllowed(string role, string verb)
{
// allow all verbs if user is "admin"
if(string.Equals("admin", role, StringComparison.OrdinalIgnoreCase)) return true;
// allow the "GET" verb if user is "support"
if(string.Equals("support", role, StringComparison.OrdinalIgnoreCase) && string.Equals("GET",verb, StringComparison.OrdinalIgnoreCase)){
return true;
};
// ... add other rules as you like
return false;
}
}
(Вы можете настроить IsAllowed(role, verb)
дальше, если у вас есть больше правил)
И сказать ASP. NET Основные способы обработки этих правил с AuthorizationHandler:
public class GlobalVerbRoleHandler : AuthorizationHandler<GlobalVerbRoleRequirement>
{
private readonly IHttpContextAccessor _httpContextAccessor;
public GlobalVerbRoleHandler(IHttpContextAccessor httpContextAccessor)
{
this._httpContextAccessor = httpContextAccessor;
}
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, GlobalVerbRoleRequirement requirement)
{
// check whether the user has required roles for current verb
var roles = context.User.FindAll(c => string.Equals(c.Type,ClaimTypes.Role)).Select(c => c.Value);
var verb= _httpContextAccessor.HttpContext?.Request.Method;
if(string.IsNullOrEmpty(verb)){ throw new Exception($"request cann't be null!"); }
foreach(var role in roles){
if(requirement.IsAllowed(role,verb)){
context.Succeed(requirement);
return Task.CompletedTask;
}
}
context.Fail();
return Task.CompletedTask;
}
}
Наконец, не забудьте зарегистрировать соответствующие службы при запуске:
services.AddHttpContextAccessor();
services.AddScoped<IAuthorizationHandler, GlobalVerbRoleHandler>();
services.AddAuthorization(opts =>{
opts.DefaultPolicy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.AddRequirements(new GlobalVerbRoleRequirement())
.Build();
});
Теперь каждый [Authorize]
также будет проверить Роль против текущего HTTP Глагол автоматически.
[Authorize]
public class WorkController : ControllerBase
{
[HttpPost("something/add")]
public async Task<IActionResult> Add()
{
//add
}
[HttpGet("something/get")]
public async Task<IActionResult> Get()
{
//get
}
}