8

Próbuję utworzyć metodę sprawdzania poprawności tokena, która zwraca wartość true, jeśli token JWT jest ważny na podstawie podpisu. Nie wydaje mi się, że naprawdę muszę sprawdzić poprawność wszystkiego w tokenie, ale co właściwie oznacza token jest ważny po wywołaniu ValidateToken()? Istnienie zasady? Token out-based zawiera określone wartości? Nie wiem, kiedy zwrócić true z tej metody.Kiedy właściwość JWTSecurityTokenHandler.ValidateToken() jest rzeczywiście poprawna?

public bool ValidateToken(string tokenString) 
{ 
    var validationParameters = new TokenValidationParameters() 
    { 
     ValidIssuer = "My Company", 
     ValidAudience = ApplicationId, 
     IssuerSigningKey = JsonWebTokenSecretKey 
    }; 

    SecurityToken token = new JwtSecurityToken(); 
    var tokenHandler = new JwtSecurityTokenHandler(); 
    var principal = tokenHandler.ValidateToken(tokenString, validationParameters, out token); 

    return principal != null; 
} 

Odpowiedz

11

Sprawdzam wszystkie wartości oświadczeń ręcznie. Szukałem definitywnej odpowiedzi na to samo pytanie, ale jedyne co widziałem to to, że funkcja ValidateToken rzuci wyjątek, jeśli coś jest nie tak, więc zaczynam od zawinięcia połączenia w try-catch i zwrócenia false z połów.

To tylko moje "pierwsze zdanie" podczas sprawdzania tokena. Następnie wykonuję trochę więcej podnoszenia ciężkich przedmiotów, aby ręcznie sprawdzić pewne wartości. Na przykład, upewniam się, że wartość unique_name w sekcji Claims faktycznie istnieje jako użytkownik w mojej bazie danych, że użytkownik nie został dezaktywowany oraz inne własnościowe pliki systemowe.

public static bool VerifyToken(string token) 
    { 
     var validationParameters = new TokenValidationParameters() 
     { 
      IssuerSigningToken = new BinarySecretSecurityToken(_key), 
      ValidAudience = _audience, 
      ValidIssuer = _issuer, 
      ValidateLifetime = true, 
      ValidateAudience = true, 
      ValidateIssuer = true, 
      ValidateIssuerSigningKey = true 
     }; 

     var tokenHandler = new JwtSecurityTokenHandler(); 
     SecurityToken validatedToken = null; 
     try 
     { 
      tokenHandler.ValidateToken(token, validationParameters, out validatedToken); 
     } 
     catch(SecurityTokenException) 
     { 
      return false; 
     } 
     catch(Exception e) 
     { 
      log(e.ToString()); //something else happened 
      throw; 
     } 
     //... manual validations return false if anything untoward is discovered 
     return validatedToken != null; 
    } 

Ostatnia linia, return validatedToken != null, jest czystym przesądem z mojej strony. Nigdy nie widziałem, aby validatedToken był pusty.

+0

Witamy w Stack Overflow, Eddie. Należy pamiętać, że sekcja odpowiedzi służy wyłącznie do pełnej odpowiedzi na oryginalne pytanie, a nie na komentarz. – Celeo

+6

Przepraszam, myślałem, że odpowiadam na to pytanie, pokazując, że ustawiono właściwości sprawdzania poprawności na true, a następnie wychwytywanie wyjątków, które są zgłaszane. Czy w moim wyjaśnieniu było zbyt wiele komentarzy? –

+3

Patrząc na kod źródłowy, wygląda to tak: WalidateToken rzuci na nieważny token. https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/master/src/System.IdentityModel.Tokens.Jwt/JwtSecurityTokenHandler.cs To jest zły projekt; nie powinniśmy używać wyjątków do sterowania przepływem. Ale taki jest dzisiejszy stan biblioteki. –