簡體   English   中英

ASP.NET核心授權策略:無法進入處理程序?

[英]ASP.NET Core Authorization Policies: Can't step into the handler?

我在我的.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()));
});

......在我的控制器上,它是這樣編寫的:

[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 Forbidden錯誤。

我嘗試在ImpersonationHandler的行上放置一個斷點:

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

...但調試器永遠不會停在這里,所以我不知道問題是什么。 有人可以告訴我我做錯了什么嗎?

您似乎忘記在DI容器中注冊您的ImpersonationHandler (這確實很容易忘記):

services.AddSingleton<IAuthorizationHandler, ImpersonationHandler>();

Asp.net從容器中解析所有這些處理程序並嘗試匹配特定要求。 由於沒有注冊這樣的處理程序 - 沒有設置context.Succeed和整個授權失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM