2014-11-21 86 views
5

我在使用.net声明主体验证用户身份时。在我们的系统中,用户有多个权限(最多可以有70个)。使用JSON字符串将多个值添加到1个用户声明中

现在,而不是在每个请求上查询数据库,用户让我认为将权限作为索赔存储是很好的。我尝试将每个权限作为单独的声明存储,但即使达到10个权限也会极大地提高权限的大小。

因此,不要为1个权限添加1个索赔,我想知道如果我将所有权限都添加到1个索赔中,它是否会产生不同的结果,并且确实如此。它保持令牌的大小很小,但我有我需要的权限。

现在要做到这一点,我必须将我的所有权限从一个数组转换成JSON字符串,然后将它们保存为我的声明。为了得到声明,我可以将字符串反序列化为一个数组,并且我根本不必查询数据库。

这可以做到这一点,或者这是非常不好的做法?我在做一个定时炸弹,它会很快爆炸吗?

例这里

var identity = new ClaimsIdentity(context.Options.AuthenticationType); 
identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); 

// get user permissions 
var permissions = await _permissionService.GetAllAsync(user); 

// create list of all permissions 
List<object> claimPermissions = new List<object>(); 

foreach (var item in permissions) 
{ 
    claimPermissions.Add(new 
    { 
     Action = item.Action, 
     Type = item.Type 
    }); 
} 

// convert list to json 
var json = Newtonsoft.Json.JsonConvert.SerializeObject(claimPermissions); 

// add claim 
identity.AddClaim(new Claim("Permissions", json)); 
+0

没有人对此有什么看法? – Gillardo 2015-02-27 10:19:11

+0

我想有人回答这个问题。忘记权限部分,并把它作为70+项目。这会不好做法? – Mike 2017-06-29 13:58:27

回答

0

代码还有就是最常用的ClaimTypes类中的 System.Security.Claims.ClaimTypes安迪建议你添加为独立权利要求中的标准列表。之后,所有剩余的声明可以作为UserData添加。我不确定为什么你的应用程序有多达70个权限?在设计基础架构时,使用最佳实践是明智的,即使用基于角色的授权。我让事情变得更轻松。请记住这些是经过验证和测试的方法。 Windows Azure Active Directory具有相同的设计,但它可以处理任何身份验证和授权方案。

如果您需要更多关于如何使用Json Web Tokens来实现这种认证机制的信息,请参阅我在here上有关该主题的文章。

给定一个Jwt,这里是你如何检查用户是否有权限。

private static ClaimsPrincipal ValidateToken(string token, string secret, bool checkExpiration) 
    { 
     var jsonSerializer = new JavaScriptSerializer(); 
     var payloadJson = JsonWebToken.Decode(token, secret); 
     var payloadData = jsonSerializer.Deserialize<Dictionary<string, object>>(payloadJson); 


     object exp; 
     if (payloadData != null && (checkExpiration && payloadData.TryGetValue("exp", out exp))) 
     { 
      var validTo = FromUnixTime(long.Parse(exp.ToString())); 
      if (DateTime.Compare(validTo, DateTime.UtcNow) <= 0) 
      { 
       throw new Exception(
        string.Format("Token is expired. Expiration: '{0}'. Current: '{1}'", validTo, DateTime.UtcNow)); 
      } 
     } 

     var subject = new ClaimsIdentity("Federation", ClaimTypes.Name, ClaimTypes.Role); 

     var claims = new List<Claim>(); 

     if (payloadData != null) 
      foreach (var pair in payloadData) 
      { 
       var claimType = pair.Key; 

       var source = pair.Value as ArrayList; 

       if (source != null) 
       { 
        claims.AddRange(from object item in source 
         select new Claim(claimType, item.ToString(), ClaimValueTypes.String)); 

        continue; 
       } 

       switch (pair.Key) 
       { 
        case "name": 
         claims.Add(new Claim(ClaimTypes.Name, pair.Value.ToString(), ClaimValueTypes.String)); 
         break; 
        case "surname": 
         claims.Add(new Claim(ClaimTypes.Surname, pair.Value.ToString(), ClaimValueTypes.String)); 
         break; 
        case "email": 
         claims.Add(new Claim(ClaimTypes.Email, pair.Value.ToString(), ClaimValueTypes.Email)); 
         break; 
        case "role": 
         claims.Add(new Claim(ClaimTypes.Role, pair.Value.ToString(), ClaimValueTypes.String)); 
         break; 
        case "userId": 
         claims.Add(new Claim(ClaimTypes.UserData, pair.Value.ToString(), ClaimValueTypes.Integer)); 
         break; 
        default: 
         claims.Add(new Claim(claimType, pair.Value.ToString(), ClaimValueTypes.String)); 
         break; 
       } 
      } 

     subject.AddClaims(claims); 
     return new ClaimsPrincipal(subject); 
    } 

我希望这有助于

感谢

斯图尔特

相关问题