c# - ASP.NET Core 授权策略 : Can't step into the handler?

标签 c# asp.net-core authorization claims-based-identity

我在我的 .NET Core 应用程序中设置了基于 JWT 的声明身份验证/授权,该应用程序按预期进行了身份验证,但我的策略执行并不像我预期的那样。

我有一个需求实现和处理程序设置如下:

public class ImpersonationRequirement : IAuthorizationRequirement
{
}

public class ImpersonationHandler : AuthorizationHandler<ImpersonationRequirement>
{
    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
        ImpersonationRequirement requirement)
    {
        if (context.User.CanImpersonate()) context.Succeed(requirement);

        return Task.CompletedTask;
    }
}

我有一个像这样设置的助手:

public static bool CanImpersonate(
    this ClaimsPrincipal principal)
{
    var val = principal?.FindFirst(MyClaimTypes.CAN_IMPERSONATE)?.Value;
    return bool.TryParse(val, out var value) && value;
}

public class MyClaimTypes
{
    /// <summary>
    /// Boolean value indicating this user is authorized to impersonate other customer accounts.
    /// </summary>
    public const string CAN_IMPERSONATE = "cim";

    ...

    /// <summary>
    /// Actual name of the user impersonating the current user.
    /// </summary>
    public const string IMPERSONATING_USER = "imp";
}

...关闭我的 Startup.cs,我定义了策略:

services.AddAuthorization(options =>
{
    options.AddPolicy("Impersonator", policy => policy.Requirements.Add(new ImpersonationRequirement()));
});

...在我的 Controller 上,它是这样写的:

[Produces("application/json")]
[Authorize(Policy = "Impersonator")]
public class ImpersonationController : Controller
{
    private readonly ILogger _logger;
    private readonly ITokenManagementService _tokenManagementService;
    private readonly UserManager<MyUser> _userManager;

    public ImpersonationController(ITokenManagementService tokenManagementService, ILoggerFactory loggerFactory, UserManager<MyUser> userManager)
    {
        _tokenManagementService = tokenManagementService;
        _userManager = userManager;
        _logger = loggerFactory.CreateLogger<ImpersonationController>();
    }

    [HttpPost]
    [Route("~/api/impersonation/token")]
    [ProducesResponseType(typeof(AuthenticationResponse), 200)]
    [ProducesResponseType(typeof(Exception), 500)]
    public async Task<IActionResult> Impersonate([FromBody] string userNameToImpersonate)
    {
        try
        {
            var impersonated = await _userManager.FindByNameAsync(userNameToImpersonate);
            if (impersonated == null) throw new EntityNotFoundException($"Unable to find user '{userNameToImpersonate}' in the data store.");
            var actualUserId = User.UserId();
            var token = await _tokenManagementService.GenerateJwt(impersonated.Id, actualUserId);
            var refresh = await _tokenManagementService.GenerateRefreshToken(impersonated.Id, actualUserId);
            var response = new AuthenticationResponse {AuthenticationToken = token, RefreshToken = refresh};
            return Ok(response);
        }
        catch (Exception ex)
        {
            return new OopsResult(ex);
        }
    }
}

如果我在注释掉 AuthorizeAttribute 的情况下运行它,我可以查看用户的声明,并且“cim: true”在声明枚举中,但是如果我在运行它时使用AuthorizeAttribute 已启用,我收到 403 禁止错误。

我尝试在 ImpersonationHandler 的行上放置一个断点:

if (context.User.CanImpersonate()) context.Succeed(requirement);

...但是调试器从未在此处停止,所以我不知道问题出在哪里。有人可以告诉我我做错了什么吗?

最佳答案

您似乎忘记在 DI 容器中注册您的 ImpersonationHandler(这确实很容易忘记):

services.AddSingleton<IAuthorizationHandler, ImpersonationHandler>();

Asp.net 从容器中解析所有此类处理程序并尝试匹配特定要求。由于没有注册这样的处理程序 - 没有设置 context.Succeed 并且整个授权失败。

关于c# - ASP.NET Core 授权策略 : Can't step into the handler?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49694599/

相关文章:

c# regex 查找和替换重用匹配文本的一部分

c# - 使用偶尔为空属性的 LINQ SequenceEqual 扩展方法

c# - 如何在 C# 中使用通用接口(interface)从子对象引用父对象?

asp.net-core - .net 核心 asp-for 小数点丢失小数位

c# - 如何使用 AWS 身份验证保护我的 wcf 服务

c# - BeginRequest 被调用两次

c# - 在 ASP.NET Core 中通过 DI 从初始化对象初始化对象

c# - 为什么 Entity Framework Core 2.2 C# 在使用现有嵌套实体插入新实体时会响应错误

express - vue中的路由中间件

python - 在 Django 中扩展 AbstractUser 的正确方法?