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

Était-ce utile?

La 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.

Autres conseils

Try this

var id = ClaimsPrincipal.Current.Identity as ClaimsIdentity;
var roles = id.FindAll(x => x.Type == ClaimTypes.Role).Select(x=> x.Value).ToArray();
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top