如何在代码中而不是使用AuthorizeAttribute检查ASP.NET身份验证策略?

时间:2019-10-21 10:16:22

标签: c# asp.net-core authorization

在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的策略”?

1 个答案:

答案 0 :(得分:1)

使用IAuthorizationService执行imperative authorization。在TagHelper类内部使用时,它比文档中显示的要复杂得多,因为它们无法直接访问HttpContextUser

这是一种使用[ViewContext]属性作为获取HttpContextUser的方法,并使用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属性中指示失败的原因。