简体   繁体   English

检查操作 controller 中的授权策略

[英]Check authorization policy inside the action controller

Because of the API is shared with admin and user.因为 API 与管理员和用户共享。 So I want to check the policy inside the action if the user id not equal with the parameter.因此,如果用户 ID 与参数不相等,我想检查操作中的策略。

To simplify, this application using jwt token as the access token.为简化起见,此应用程序使用 jwt 令牌作为访问令牌。 So as for now have 2 roles which it User and Admin .所以现在有两个角色,它是UserAdmin So I add policy based on claims for this roles.因此,我根据此角色的声明添加了策略。 Here how I generate the policy in startup.cs这里我如何在startup.cs中生成策略

public static IServiceCollection AddCustomAuthorizationPolicy(this IServiceCollection services) 
{
    services.AddAuthorization(options = >options.AddPolicy("UserOnly", policy = >policy.RequireClaim(CustomClaimTypes.UserManagement, "User", "Admin")));
    services.AddAuthorization(options = >options.AddPolicy("RequireAdmin", policy = >policy.RequireClaim(CustomClaimTypes.UserManagement, "Admin")));

    return services;
}

UserOnly allow both of roles. UserOnly允许两个角色。 RequireAdmin for admin only. RequireAdmin仅用于管理员。

Here is the current API I do for change the password这是我为更改密码所做的当前 API

[HttpPost("{id}/change-password")]
[Authorize(Policy = "RequireAdmin")]
public async Task <IActionResult> ChangePassword([FromRoute] string id, [FromBody] UserChangePasswordViewModel model) 
{
    
    //This authorize filter require admin.
    //But I also want allow user to access
    
    var user = await _userManager.FindByIdAsync(id);

    if (user == null) return BadRequest("User not found");
    
    //My business logic here

}

So I change to UserOnly which allow both of roles to access it所以我改为UserOnly允许两个角色访问它

[HttpPost("{id}/change-password")]
[Authorize(Policy = "UserOnly")]
public async Task < IActionResult > ChangePassword([FromRoute] string id, [FromBody] UserChangePasswordViewModel model) 
{
    var getCurrentUserId = _identityService.GetUserIdentity();
    
    var user = await _userManager.FindByIdAsync(id);

    if (user == null) return BadRequest("User not found");
    
    if(getCurrentUserId != id)
    {
        //Check if this user is admin
        if(!isAdmin) //<-- Here I want to check the policy
        {
            //Response 403 forbidden
            
        }
    }

    //My business logic here

}

But I not really sure how to check policy inside the action.但我不太确定如何检查行动内部的政策。 Any better suggestion?有更好的建议吗? or need to use HttpContext.User for find the claim and check the value?还是需要使用HttpContext.User来查找声明并检查值?

Try: User.IsInRole("Admin")试试: User.IsInRole("Admin")

In my opinion, there is no need to call RequireAdmin policy again in the action method to check the user is admin or not.在我看来,没有必要在 action 方法中再次调用 RequireAdmin 策略来检查用户是否为管理员。

You could directly get the CustomClaimTypes.UserManagement claim value from User in the action method.您可以在 action 方法中直接从User获取 CustomClaimTypes.UserManagement 声明值。 Then you could write some logic to check the user is admin or not.然后你可以写一些逻辑来检查用户是否是管理员。

More details about how to get the CustomClaimTypes.UserManagement claim value and check it,you could refer to below codes:有关如何获取 CustomClaimTypes.UserManagement 声明值并检查它的更多详细信息,您可以参考以下代码:

    public async Task<IActionResult> Get()
    {
        string role = User.Claims.FirstOrDefault(x => x.Type == CustomClaimTypes.UserManagement).Value;
        if (role != "Admin")
        {
            return Forbid();
        }
        return Ok(new string[] { "value1", "value2" });

    } 

Result:结果:

在此处输入图像描述

You can make a dynamic policy decision by taking a dependency in your controller on IAuthorizationService and calling the IAuthorizationService.AuthorizeAsync method.您可以通过在您的 controller 中依赖IAuthorizationService并调用IAuthorizationService.AuthorizeAsync方法来做出动态策略决策。 An example of some fictional controller:一些虚构的 controller 的示例:

private readonly IAuthorizationService _authorizationService;

public MyController(IAuthorizationService authorizationService) 
{
    _authorizationService = authorizationService;
}

[HttpPost("{id}/protected-action")]
public async Task <IActionResult> SomeDynamicallyProtectedAction() 
{
    var isAdminEvaluationResult =
        await _authorizationService.AuthorizeAsync(User, null, "RequireAdmin");

    if (!isAdminEvaluationResult.Succeeded)
    {
        return Forbid();
    }

    // ...continue processing the request
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM