在为Owin实现自定义角色提供程序时,GetRolesForUser中的递归调用会导致堆栈溢出

时间:2014-03-17 16:32:33

标签: asp.net-mvc claims-based-identity owin roleprovider katana

我正在使用ASP NET MVC 5和Owin进行身份验证。 在我的帐户控制器中,我设置了这样的用户:

  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);

显然,我正在将(单个)角色添加到身份中。 在后续请求中,当我呈现具有特定于角色的内容的视图时,将调用我的自定义角色提供程序类'GetRolesForUser(字符串用户名)。 我所要做的就是从授权用户解压缩角色声明并返回这些角色的列表。 但是,当迭代所有声明IEnumerable时,在迭代了所有声明之后,GetRolesForUser会再次被调用,最后我将进入一个永无止境的递归调用循环。

只有一个角色,我通过在找到第一个角色类型声明后立即从函数返回来创建了一个变通方法:

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 };
            }

但是,这样的事情永远不会完成:

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

为什么呢? 迭代索赔调用GetRolesForUser? 如果我有多角色情景,我将如何获得所有角色的数组?

谢谢,

伊戈尔

1 个答案:

答案 0 :(得分:-1)

试试这个

var id = ClaimsPrincipal.Current.Identity as ClaimsIdentity;
var roles = id.FindAll(x => x.Type == ClaimTypes.Role).Select(x=> x.Value).ToArray();