Décodage et vérification de JWT token à l'aide du système.IdentityModel.Jeton.Jwt
j'ai utilisé la bibliothèque JWT pour décoder un jeton Web Json, et je voudrais passer à L'implémentation officielle JWT de Microsoft, système.IdentityModel.Jeton.Jwt .
la documentation est très clairsemée, donc j'ai du mal à comprendre comment accomplir ce que j'ai fait avec la bibliothèque JWT. Avec la bibliothèque JWT, il y a une méthode de décodage qui prend la base64 encodée JWT et la transforme en JSON qui peut ensuite être désérialisé. J'aimerais faire quelque chose de similaire en utilisant le système.IdentityModel.Jeton.Jwt, mais après avoir creusé assez longtemps, ne peut pas comprendre comment.
pour ce que ça vaut, je suis en train de lire le JWT token à partir d'un cookie, pour utilisation avec le cadre d'identité de Google.
Toute aide serait appréciée.
2 réponses
dans le colis il y a une classe appelée JwtSecurityTokenHandler
qui dérive de System.IdentityModel.Tokens.SecurityTokenHandler
. Dans WIF, c'est la classe de base pour la désérialisation et la sérialisation des jetons de sécurité.
la classe a une méthode ReadToken(String)
qui prendra votre chaîne base64 encodée JWT et retournera un SecurityToken
qui représente le JWT.
le SecurityTokenHandler
a aussi une méthode ValidateToken(SecurityToken)
qui prend votre SecurityToken
et crée un ReadOnlyCollection<ClaimsIdentity>
. Généralement pour JWT, cela contiendra un seul objet ClaimsIdentity
qui a un ensemble de revendications représentant les propriétés de la JWT originale.
JwtSecurityTokenHandler
définit certaines surcharges supplémentaires pour ValidateToken
, en particulier, il a une surcharge ClaimsPrincipal ValidateToken(JwtSecurityToken, TokenValidationParameters)
. L'argument TokenValidationParameters
vous permet de spécifier le certificat de signature du token (comme une liste de X509SecurityTokens
). Il a également une surcharge qui prend le JWT comme un string
plutôt que d'un SecurityToken
.
le code pour faire ceci est assez compliqué, mais peut être trouvé dans le Global.asax.code cx (classe TokenValidationHandler
) dans l'échantillon du développeur appelé "Adal-Native App to REST service-Authentication with ACS via Browser Dialog", situé à
http://code.msdn.microsoft.com/AAL-Native-App-to-REST-de57f2cc
la classe JwtSecurityToken
comporte également des méthodes supplémentaires qui ne sont pas classe de base SecurityToken
, telle qu'une propriété Claims
qui obtient les revendications contenues sans passer par la collection ClaimsIdentity
. Il a aussi une propriété Payload
qui renvoie un objet JwtPayload
qui vous permet d'obtenir le JSON brut du JSON du jeton. Cela dépend de votre scénario qui s'approche le plus approprié.
la documentation générale (c.-à-d. non spécifique à JWT) pour la classe SecurityTokenHandler
est à
http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.securitytokenhandler.aspx
selon votre application, vous pouvez configurer le gestionnaire JWT dans le pipeline WIF exactement comme n'importe quel autre gestionnaire.
il y a 3 échantillons de celui-ci en usage dans différents types d'application à
probablement, on répondra à vos besoins ou au moins être adaptable à eux.
je me demande juste pourquoi utiliser certaines bibliothèques pour le décodage et la vérification des tokens JWT.
Le jeton JWT codépeut être créé en utilisant le pseudocode suivant
var headers = base64URLencode(myHeaders);
var claims = base64URLencode(myClaims);
var payload = header + "." + claims;
var signature = base64URLencode(HMACSHA256(payload, secret));
var encodedJWT = payload + "." + signature;
il est très facile de faire sans bibliothèque spécifique. En utilisant le code suivant:
using System;
using System.Text;
using System.Security.Cryptography;
public class Program
{
// More info: https://stormpath.com/blog/jwt-the-right-way/
public static void Main()
{
var header = "{\"typ\":\"JWT\",\"alg\":\"HS256\"}";
var claims = "{\"sub\":\"1047986\",\"email\":\"jon.doe@eexample.com\",\"given_name\":\"John\",\"family_name\":\"Doe\",\"primarysid\":\"b521a2af99bfdc65e04010ac1d046ff5\",\"iss\":\"http://example.com\",\"aud\":\"myapp\",\"exp\":1460555281,\"nbf\":1457963281}";
var b64header = Convert.ToBase64String(Encoding.UTF8.GetBytes(header))
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
var b64claims = Convert.ToBase64String(Encoding.UTF8.GetBytes(claims))
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
var payload = b64header + "." + b64claims;
Console.WriteLine("JWT without sig: " + payload);
byte[] key = Convert.FromBase64String("mPorwQB8kMDNQeeYO35KOrMMFn6rFVmbIohBphJPnp4=");
byte[] message = Encoding.UTF8.GetBytes(payload);
string sig = Convert.ToBase64String(HashHMAC(key, message))
.Replace('+', '-')
.Replace('/', '_')
.Replace("=", "");
Console.WriteLine("JWT with signature: " + payload + "." + sig);
}
private static byte[] HashHMAC(byte[] key, byte[] message)
{
var hash = new HMACSHA256(key);
return hash.ComputeHash(message);
}
}
le décodage du jeton est une version inversée du code ci-dessus.Pour vérifier la signature vous aurez besoin de la même et comparer partie de la signature avec une signature calculée.
mise à jour: pour ceux qui se battent comment faire base64 urlsafe encoding / décodage s'il vous plaît voir un autre ainsi question , et aussi wiki et RFC