Yahya Hussein
Yahya Hussein

Reputation: 9121

How to allow specific roles to access API using identityserver3.accesstokenvalidation

I have an Identityserver4 that is providing access tokens to clients.

On my API, I want to be sure that client is allowed to access specific scope and that User belongs to a specific role before I give this user access to API.

To do that I am using Identityserver3.accesstokenvalidation package.

 app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
        {
            Authority = "Authority",
            RequiredScopes = new[] { "MyScope" },
        });

This is blocking users that do not have access token from accessing my API, also it is checking if the provided scope is "MyScope".

My question is how do I also check that user has a specific role before allowing access to API.

Upvotes: 2

Views: 251

Answers (1)

Julia Savinkova
Julia Savinkova

Reputation: 563

You could put attribute [Authorize(Roles = "Admin")] for specific controller. If you need more advanced logic with claims you need to specify your own attribute e.g. AuthorizePermissionAttribute and use it with controller [AuthorizePermission("Preview")]:

public class AuthorizePermissionAttribute : AuthorizeAttribute
{
    private readonly string grantedPermission;

    public AuthorizePermissionAttribute(string permission)
    {
        this.grantedPermission = permission ?? throw new ArgumentNullException(nameof(permission));
    }

    protected override bool IsAuthorized(HttpActionContext actionContext)
    {
        var claims = actionContext.ControllerContext.RequestContext.Principal as ClaimsPrincipal;

        var permission = claims?.FindFirst(this.grantedPermission);

        return permission != null && Convert.ToBoolean(permission.Value);
    }

    protected override void HandleUnauthorizedRequest(HttpActionContext actionContext)
    {
        var response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "insufficient_permissions");

        actionContext.Response = response;
    }
}

Also you need to put in Startup.cs:

   JwtSecurityTokenHandler.InboundClaimTypeMap = new Dictionary<string, string>();

   app.UseIdentityServerBearerTokenAuthentication(new IdentityServerBearerTokenAuthenticationOptions
   {
      Authority = ConfigurationManager.AppSettings["IdentityProviderApi"],
      PreserveAccessToken = true
   });

Without JwtSecurityTokenHandler.InboundClaimTypeMap it will return always Unauthorized status code.

Upvotes: 1

Related Questions