2014-11-21 12 views
5

Używam .net roszczenia główne podczas uwierzytelniania użytkownika. W naszym systemie użytkownik ma wiele uprawnień (może mieć do 70).Dodawanie wielu wartości do 1 roszczenia użytkownika przy użyciu ciągu JSON

Teraz zamiast wysyłać zapytania do bazy danych przy każdym żądaniu, które robi użytkownik, pomyślałem, że dobrze byłoby przechowywać uprawnienia jako roszczenie. Próbowałem przechowywać każde pozwolenie jako oddzielne roszczenie, ale nawet uzyskanie 10 uprawnień znacznie zwiększa rozmiar tokena.

Więc zamiast dodawać 1 wniosek o 1 pozwolenie, zastanawiałem się, czy byłoby inaczej, gdybym dodał wszystkie uprawnienia do 1 roszczenia, i to robi. Zachowuje niewielki rozmiar tokena, ale mam uprawnienia, których potrzebuję.

Teraz, aby to zrobić, musiałem przekonwertować wszystkie moje uprawnienia z tablicy, na ciąg JSON, a następnie zapisać je jako moje roszczenie. Aby uzyskać roszczenie, mogę deserializować łańcuch z powrotem do tablicy i wcale nie będę musiał wysyłać zapytania do bazy danych.

Czy można to zrobić, czy jest to bardzo zła praktyka? Czy robię tykanie bomby zegarowej i wkrótce to się rozwali?

Przykładowy kod tutaj

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

Czy ktoś ma jakieś opinie na ten temat? – Gillardo

+0

Chciałbym, aby ktoś odpowiedział na pytanie. Zapomnij o części Permissions i weź ją jako 70+ przedmiotów. Czy to byłoby złe Ćwiczenie? – Mike

Odpowiedz

0

Jest to standardowa lista większość powszechnie stosowanych ClaimTypes w klasie System.Security.Claims.ClaimTypes Andi Proponuję dodać je jako odrębne roszczenia. Następnie wszystkie pozostałe roszczenia można dodać jako tylko UserData. Nie wiem, dlaczego Twoja aplikacja ma maksymalnie 70 uprawnień? Podczas projektowania infrastruktury dobrze jest stosować najlepsze praktyki, takie jak autoryzacja oparta na rolach. Ułatwia sprawy. I pamiętaj, że są to wypróbowane i przetestowane metody. Usługa Active Directory Windows Azure ma taki sam wygląd, a mimo to może obsłużyć dowolny scenariusz uwierzytelniania i autoryzacji.

Jeśli potrzebujesz więcej informacji o tym, jak używać Tokena internetowego Json do wdrożenia takiego mechanizmu uwierzytelniania, zobacz mój artykuł na ten temat pod adresem here.

Biorąc pod uwagę Jwt, oto, w jaki sposób sprawdzić, czy użytkownik ma uprawnienia.

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

Mam nadzieję, że to pomoże

Dzięki

Stewart

Powiązane problemy