#asp.net-core #asp.net-core-webapi #authorize-attribute
#asp.net-ядро #asp.net-core-webapi #authorize-атрибут
Вопрос:
У меня есть .NET Core 3 WebAPI, где я хочу использовать пользовательскую авторизацию на основе политик, где одна из политик имеет несколько требований.
Я добавил политику в Startup.ConfigureServices()
и добавил MyCustomPolicyHandler
в DI:
public virtual void ConfigureServices(IServiceCollection services)
{
services.AddAuthorization(options =>
{
options.AddPolicy("MyCustomPolicy", policy =>
{
policy.Requirements.Add(new RequirementA());
policy.Requirements.Add(new RequirementB());
policy.Requirements.Add(new RequirementC());
policy.Requirements.Add(new RequirementD());
});
services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
});
}
Я реализовал MyCustomPolicyHandler
, используя пример из этой документации:
Авторизация на основе политики в ASP.NET Ядро
public class MyCustomPolicyHandler: IAuthorizationHandler
{
public Task HandleAsync(AuthorizationHandlerContext context)
{
var pendingRequirements = context.PendingRequirements.ToList();
Console.WriteLine($"MyCustomPolicyHandler: {pendingRequirements.Count} requirements");
foreach (var requirement in pendingRequirements)
{
if(requirement is RequirementA) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementB) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementC) {
// do stuff to check the requirements
context.Succeed(requirement);
}
else if(requirement is RequirementD) {
// do stuff to check the requirements
context.Succeed(requirement);
}
}
return Task.CompletedTask;
}
}
Затем я применяю политику к одному из действий контроллера:
public class MyController
{
[HttpGet]
[Authorize(Policy="MyCustomPolicy")]
public ActionResult<SomeViewModel> Get(int id) {
// do stuff
return Ok(vm);
}
}
Проблема, с которой я сталкиваюсь, заключается в отсутствии требований, связанных с политикой. В Console.WriteLine()
сообщении отображается 0 требований:
MyCustomPolicyHandler: 0 requirements
Если я перенесу политику на контроллер, требования будут присутствовать:
[Authorize(Policy="MyCustomPolicy")]
public class MyController
{
[HttpGet]
public ActionResult<SomeViewModel> Get(int id) {
// do stuff
return Ok(vm);
}
}
MyCustomPolicyHandler: 4 requirements
Однако мне нужно, чтобы эта политика применялась к действию, а не к контроллеру. Атрибут [Authorize(Policy=»MyCustomPolicy»)] должен работать на уровне действия.
Есть идеи, почему это не работает?
Спасибо.
Ответ №1:
Потому что место, куда MyCustomPolicyHandler
вводится, неуместно. Его необходимо поместить вне AddAuthorization
.
services.AddAuthorization(options =>
{
options.AddPolicy("MyCustomPolicy", policy =>
{
policy.Requirements.Add(new RequirementA());
//...
});
});
services.AddScoped<IAuthorizationHandler, MyCustomPolicyHandler>();
Комментарии:
1. хороший улов! Не могли бы вы показать мне, где вы применили политику (к контроллеру или действию?). К сожалению, я все еще показываю
pendingRequirements = 0
.2. Я поместил политику в действие.