Because of the API is shared with admin and user. So I want to check the policy inside the action if the user id not equal with the parameter.
To simplify, this application using jwt token as the access token. So as for now have 2 roles which it User
and Admin
. So I add policy based on claims for this roles. Here how I generate the policy in 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. RequireAdmin
for admin only.
Here is the current API I do for change the password
[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
[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?
You can make a dynamic policy decision by taking a dependency in your controller on IAuthorizationService
and calling the IAuthorizationService.AuthorizeAsync
method. An example of some fictional 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
}
Try:
User.IsInRole("Admin")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With