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

时间:2019-06-30 21:44:25

标签: c# authentication asp.net-core asp.net-core-identity

我正在尝试使用自定义标签帮助程序来验证当前授权的用户是否具有特定角色。我想使用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);
}

2 个答案:

答案 0 :(得分:2)

合并ViewContextAttributeHttpContext.UserUserManager.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的调用,该调用返回由IdentityUser(或自定义类型)使用的身份实施。
  3. 我们将此identityUser值传递给UserManager.IsInRoleAsync

答案 1 :(得分:0)

我最终重写了一些逻辑:

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();
    }