在ASP.NET Core的授权系统中检查策略是否已实现的通常方法是在ConfigureServices
中设置策略,如下所示:
services.AddAuthorization(conf => {
conf.AddPolicy("UserHasRecentPassport", policy => policy.RequireAssertion(ctx => { return ctx.User.HasRecentPassport(); }));
}
...,然后使用AuthorizeAttribute
将其指定为控制器或操作,如下所示:
[Authorize("UserHasRecentPassport")]
public class HomeController : Controller {
public IActionResult Index() {
return View();
}
}
但是,我正在编写一个标记助手,它需要检查是否满足特定的策略。因此,我只需要在代码中检查它,而不要使用AuthorizeAttribute
方法。像这样:
public override void Process(TagHelperContext context, TagHelperOutput output) {
output.TagName = null;
if (!policyRequirementIsMet("UserHasRecentPassport")) {
output.SuppressOutput();
}
}
我有什么方法可以实现policyRequirementIsMet
,然后转到ASP.NET Core并说“告诉我是否满足名称X的策略”?
答案 0 :(得分:1)
使用IAuthorizationService
执行imperative authorization。在TagHelper
类内部使用时,它比文档中显示的要复杂得多,因为它们无法直接访问HttpContext
和User
。
这是一种使用[ViewContext]
属性作为获取HttpContext
和User
的方法,并使用DI获取IAuthorizationService
的方法:
public class PassportTagHelper : TagHelper
{
private readonly IAuthorizationService authorizationService;
public PassportTagHelper(IAuthorizationService authorizationService)
{
this.authorizationService = authorizationService;
}
[ViewContext]
public ViewContext ViewContext { get; set; }
public override async Task ProcessAsync(TagHelperContext ctx,
TagHelperOutput output)
{
var httpContext = ViewContext.HttpContext;
var authorizationResult = await authorizationService
.AuthorizeAsync(httpContext.User, "UserHasRecentPassport");
if (!authorizationResult.Succeeded)
output.SuppressOutput();
}
}
注意事项:
HttpContext
属性访问ViewContext
,该属性是通过使用[ViewContext]
属性修饰来设置的。Process
更改为ProcessAsync
,以便我们可以使用await
。AuthorizeAsync
返回的值是一个AuthorizationResult
,它通过其Succeeded
属性指示成功,并在其Failure
属性中指示失败的原因。