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.

78
demandé sur w.brian 2013-09-08 00:55:38

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 à

http://code.msdn.microsoft.com/site/search?f%5B0%5D.Type=SearchText&f%5B0%5D.Value=aal&f%5B1%5D.Type=User&f%5B1%5D.Value=Azure%20AD%20Developer%20Experience%20Team&f%5B1%5D.Text=Azure%20AD%20Developer%20Experience%20Team

probablement, on répondra à vos besoins ou au moins être adaptable à eux.

116
répondu Mike Goodwin 2013-09-20 15:56:42

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

17
répondu Regfor 2018-01-24 17:48:15