2014-11-21 6 views
5

Sto utilizzando .net reclama il principal quando autentichi un utente. Nel nostro sistema un utente ha più permessi (può essere fino a 70).Aggiunta di più valori in 1 reclamo utente utilizzando la stringa JSON

Ora invece di interrogare il database su ogni richiesta, un utente ritiene che sarebbe opportuno archiviare le autorizzazioni come richiesta. Ho provato a memorizzare ogni autorizzazione come richiesta separata, ma persino ottenere 10 permessi fa aumentare enormemente la dimensione del token.

Così invece di aggiungere 1 richiesta per 1 permesso, mi chiedevo se avrebbe fatto un altro se avessi aggiunto tutte le autorizzazioni a 1 reclamo, e lo fa. Mantiene le dimensioni del token piccolo, ma ho i permessi di cui ho bisogno.

Ora per fare questo, ho dovuto convertire tutte le mie autorizzazioni da un array, in una stringa JSON e quindi salvarle come richiesta. Per ottenere il reclamo, posso quindi deserializzare la stringa in una matrice e non devo assolutamente interrogare il database.

Questo è ok per fare questo, o è una pessima pratica? Sto facendo una bomba a orologeria e sta per esplodere presto facendo questo?

codice di esempio qui

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

Qualcuno ha qualche opinione su questo? – Gillardo

+0

Vorrei che qualcuno rispondesse alla domanda. Dimentica la parte Autorizzazioni e prendila come 70+ elementi. Sarebbe una cattiva pratica? – Mike

risposta

0

C'è un elenco standard della maggior parte dei ClaimTypes comunemente utilizzati nella classe System.Security.Claims.ClaimTypes andi suggerisco di aggiungere quelli come domande distinte. Dopo di che tutte le richieste rimanenti possono essere aggiunte come solo UserData. Non sono sicuro del motivo per cui la tua app ha fino a 70 autorizzazioni? Quando si progetta la propria infrastruttura è consigliabile utilizzare le migliori pratiche, che è l'utilizzo dell'autorizzazione basata sui ruoli. T facilita le cose E ricorda che questi sono metodi provati e testati. Windows Azure Active Directory ha lo stesso design e tuttavia può gestire qualsiasi scenario di autenticazione e autorizzazione.

Se sono necessarie ulteriori informazioni su come utilizzare i Token Web JSON per implementare tale meccanismo di autenticazione, vedere il mio articolo sull'argomento here.

Dato un Jwt, ecco come si controllerebbe se un utente ha i permessi.

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

Spero che questo aiuta

Grazie

Stewart