Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IsInRole return false even if there is role in claims

I am working on claim base authentication and it is working fine. Now I want to add role autorization. I have role claim for user (eg. "Admin")

When the IsInRole() method is called, there is a check made to see if the current user has that role. In claims-aware applications, the role is expressed by a role claim type that should be available in the token. The role claim type is expressed using the following URI: http://schemas.microsoft.com/ws/2008/06/identity/claims/role

//Include all claims
//claims is List<Claim> with all claims
 var id = new ClaimsIdentity(claims, "Cookies");
 Request.GetOwinContext().Authentication.SignIn(id);

If i check if user is in role I will get false. Although I have Role claim with "Admin" value

User.IsInRole("Admin");

Also authorize attrubute on my api will not work

[Authorize (Roles = "Admin")]

I probably misih logic how to make roles visible to User. Probably is not enough to just have Roles in list of claims?

like image 879
Raskolnikov Avatar asked Jan 29 '16 09:01

Raskolnikov


1 Answers

If your service is using Windows authentication, then the IPrincipal.Identity you receive will be of type WindowsPrincipal. It's a little misleading, but the ClaimType that WindowsPrincipal.IsInRole() looks for is not ClaimTypes.Role as you might reasonably expect, but ClaimTypes.GroupSid.

However, you should not assume the actual ClaimType that the current Identity uses for specifying roles because different types of identity use different values. Instead you should reference the ClaimsIdentity.RoleClaimType property.

We have implemented a IAuthenticationFilter along the following lines:

public Task AuthenticateAsync(HttpAuthenticationContext context, cancellationToken)
{
    var principal = context.Principal;

    if(principal.Identity is ClaimsIdentity && principal.Identity.IsAuthenticated)
    {
        var ci = (ClaimsIdentity)principal.Identity;
        // get the user's additional roles from somewhere and add Claims
        ci.AddClaim(new Claim(ci.RoleClaimType, "MyRole"));
    }
}

This allows us to use the standard AuthorizeAttribute mechanism in our ASP.Net Controllers. e.g.

[Authorize(Roles="MyRole")]
public IHttpActionResult Get()
{
    //authenticated and authorised code here
}

See ClaimsIdentity.RoleClaimType on MSDN for further clarification.

Please note: adding user-defined roles to the WindowsPrincipal can cause problems. It seems that the current implementation of .Net Framework 4.5 (as of April 2017) will sometimes throw an exception when checking roles, expecting the details of the role to be available from Active Directory. See this question for an alternative approach.

like image 135
Rob Avatar answered Sep 21 '22 23:09

Rob