2014-11-21 58 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); 
    } 

我希望這有助於

感謝

斯圖爾特

相關問題