0

In my project, I have number of APIs using JWT token which are decorated with [Authorize] attribute and it run well.

[HttpPost]
[Authorize(Roles = "Administrator")]
public IActionResult GetCustomers()
{
   return Ok();
}

If I provide null, wrong JWT token or JWT token with not Administrator role, it return response like picture below: enter image description here

But I want to custom response like that:

{
  "StatusCode" : 401,
  "message": "You need Administrator role"
}

And I follow to this reference to custom authorize attribute.

My custom:

public class ClaimRequirementAttribute : TypeFilterAttribute
    {
        public ClaimRequirementAttribute(string claimType, string claimValue) : base(typeof(CustomAuthorization))
        {
            Arguments = new object[] { new Claim(claimType, claimValue) };
        }
    }


    public class CustomAuthorization : IAuthorizationFilter
    {
        readonly Claim _claim;

        public CustomAuthorization(Claim claim)
        {
            _claim = claim;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var hasClaim = context.HttpContext.User.Claims.Any(c => c.Type == _claim.Type && c.Value == _claim.Value);
            if (!hasClaim)
            {
                context.Result = new ForbidResult($"You need {_claim.Value} role");
            }
        }
    }

And my controller:

[HttpPost]
[ClaimRequirement(ClaimTypes.Role, "Administrator")]
public IActionResult GetCustomers()
    {
       return Ok();
    }

But I have 2 problems:

  • The first problem is that if I provide null, wrong JWT token or JWT token with not administrator role, I have this error: enter image description here

  • And the second is whether there is a simple way to solve it ?

Thanks for your attention.

Edit: the first question i solved it, the solution in my comment

  • The first question is from my bad, I didn't read carefully about constructor of ForbidResult(). Replace to this code below to solve problem: context.Result = new ObjectResult(new { message= $"You need {_claim.Value} role" }) { StatusCode = 403 } – Đoàn Đức Bảo Mar 08 '22 at 10:38
  • 1
    What do you mean for the second question? Do you mean you want to return custom error message in another way which is more simple? – Rena Mar 09 '22 at 07:44
  • @Rena yes, I like to return custom error message, when I use default [Authorize] attribute it only return status code like the first picture. My solution is quite complicated. – Đoàn Đức Bảo Mar 09 '22 at 08:26
  • 1
    Hi, actually I think your code is not complicated. For improvement, if you just want to authorize for only one action, you can inherits `Attribute, IAuthorizationFilter` to just use one custom class. – Rena Mar 09 '22 at 09:04

0 Answers0