如何访问授权用户自定义标签助手

how to access authorized user a custom tag helper

我正在尝试使用自定义标签助手来验证当前授权者是否处于特定角色。我想使用UserManager.IsInRoleAsync(),但我需要传入一个User对象。

如何访问当前授权用户?

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
    base.PreProcess(context, output);

    bool isInRole = _um.IsInRoleAsync(????, this.Roles); ;

    var policy = await AuthorizationPolicy.CombineAsync(_policy, new[] { this });
    var authResult = await _eva.AuthenticateAsync(policy, _http.HttpContext);
    var authorizeResult = await _eva.AuthorizeAsync(policy, authResult, _http.HttpContext, null);
}

合并 ViewContextAttribute, HttpContext.User and UserManager.GetUserAsync:

[ViewContext]
public ViewContext ViewContext { get; set; }

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
    // ...

    var claimsPrincipal = ViewContext.HttpContext.User;
    var identityUser = await _um.GetUserAsync(claimsPrincipal);

    if (identityUser == null)
    {
        // Either no user is signed in or there's no match for the user in Identity.
        // ...
    }

    bool isInRole = _um.IsInRoleAsync(identityUser, this.Roles);

    // ...
}

下面是对正在发生的事情的细分:

  1. 使用 属性 修饰 [ViewContext],我们可以访问 ViewContext 及其 HttpContext 属性.
  2. 给定一个 HttpContext,我们可以访问它的 User 属性 并将其传递给对 UserManager.GetUserAsync 的调用,其中 returns IdentityUser(或自定义类型)由 Identity 实现使用。
  3. 我们将此 identityUser 值传递给 UserManager.IsInRoleAsync

我最终重写了一些逻辑::

var foo = new AuthorizationPolicyBuilder()
            .RequireAuthenticatedUser();

    if (!this.Roles.IsNull())
    {
        foo.RequireRole(this.Roles.Split(","));
    }

    if (!this.AuthenticationSchemes.IsNull())
    {
        foo.AddAuthenticationSchemes(this.AuthenticationSchemes);
    }

    var policy = foo.Build();
    var authResult = await _eva.AuthenticateAsync(policy, _http.HttpContext);
    var authorizeResult = await _eva.AuthorizeAsync(policy, authResult, _http.HttpContext, null);

    if (!authorizeResult.Succeeded)
    {
        output.SuppressOutput();
    }