Question

I'm using ASP NET MVC 5 and Owin for authentication. In my Account controller I setup the user like this:

  var claims = new List<Claim>();
  claims.AddRange(new List<Claim>
                                {
                                    new Claim(ClaimTypes.Name, "john"),                                    
                                    new Claim(ClaimTypes.Sid, "123"),
                                    (...)
                                });
  var id = new ClaimsIdentity(claims, DefaultAuthenticationTypes.ApplicationCookie, ClaimTypes.Name, ClaimTypes.Role);
  id.AddClaim(new Claim(ClaimTypes.Role, selUser.Role));
  authenticationManager.SignIn(new AuthenticationProperties
                             {
                                IsPersistent = false
                              }, id);

Obviously, I'm adding the (single) role to the identity. On subsequent request, when I'm rendering a view that has role-specific content, my custom role provider class' GetRolesForUser(string username) get called. All I'm trying to do is to unpack the role claims from the authorized user and return the list of those roles. However, when iterating over the Claims IEnumerable, after all claims have been iterated, the GetRolesForUser gets called all over again and I end up in a never-ending recursive call loop.

Having only one role, I've created a workaround by returning from function immediately upon finding first role type claim:

public override string[] GetRolesForUser(string username) {
            var id = ClaimsPrincipal.Current.Identities.First();
            foreach (Claim c in id.Claims)
            {                
                if (c.Type == ClaimTypes.Role) return new string[] { c.Value };
            }

However, something like this will never finish:

string role = id.Claims.Where(c => c.Type == ClaimTypes.Role).Select(c => c.Value).SingleOrDefault();

Why? Iterating over claims calls GetRolesForUser? How would I get an array of all roles, if I had multiple-roles-scenario?

Thanks,

Igor

Was it helpful?

Solution

I bumped into the same situation in the context of a Umbraco project. What's worse is that years ago I went through the same, but still managed to hit a wall trying to understand what was happening...

Most likely, ClaimsPrincipal.Current is returning an instance of RolePrincipal, instead of the expected ClaimsPrincipal. Confirm web.config has the following:

<modules>
    <remove name="FormsAuthentication" />
    <remove name="RoleManager" />
</modules>

This answer has more detailed information.

OTHER TIPS

Try this

var id = ClaimsPrincipal.Current.Identity as ClaimsIdentity;
var roles = id.FindAll(x => x.Type == ClaimTypes.Role).Select(x=> x.Value).ToArray();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top