Декодирование и проверка токена JWT с помощью системы.IdentityModel.Жетоны.Агентство jwt

Я использую JWT библиотека для декодирования веб-маркера Json и хотела бы переключиться на официальную реализацию JWT от Microsoft, система.IdentityModel.Жетоны.JWT в.

документация очень скудная, поэтому мне трудно понять, как выполнить то, что я делал с библиотекой JWT. С библиотекой JWT существует метод декодирования, который принимает кодированный base64 JWT и превращает его в JSON, который затем может быть десериализован. Я хотел бы сделать что-то подобное с помощью системы.IdentityModel.Жетоны.Jwt, но после изрядного количества раскопок, не может понять, как.

для чего это стоит, я читаю токен JWT из файла cookie, для использования с Google Identity framework.

любая помощь будет оценили.

2 ответов


в пакете есть класс под названием JwtSecurityTokenHandler, который является производным от System.IdentityModel.Tokens.SecurityTokenHandler. В WIF это базовый класс для deserialising и serialising маркеры безопасности.

класс а ReadToken(String) метод, который будет принимать вашу строку JWT в кодировке base64 и возвращает SecurityToken который представляет JWT.

на SecurityTokenHandler также ValidateToken(SecurityToken) метод, который принимает ваш SecurityToken создает ReadOnlyCollection<ClaimsIdentity>. Обычно для JWT это будет содержать одно ClaimsIdentity объект, который имеет набор утверждений, представляющих свойства исходного JWT.

JwtSecurityTokenHandler определяет некоторые дополнительные перегрузки ValidateToken в частности, у него есть ClaimsPrincipal ValidateToken(JwtSecurityToken, TokenValidationParameters) перегрузка. The TokenValidationParameters аргумент позволяет указать сертификат подписи маркера (в виде списка X509SecurityTokens). Он также имеет перегрузку, которая принимает JWT как string, а не SecurityToken.

код для этого довольно сложный,но его можно найти в глобальном.асакс.код cx (TokenValidationHandler класс) в пример разработчика под названием "ADAL-Native App to REST service-аутентификация с ACS через диалог браузера", расположенный по адресу

http://code.msdn.microsoft.com/AAL-Native-App-to-REST-de57f2cc

кроме того,JwtSecurityToken класс имеет дополнительные методы, которые не на базе SecurityToken класс, например Claims свойство, которое получает содержащиеся претензии, не проходя через ClaimsIdentity коллекция. Он также имеет Payload свойство, которое возвращает JwtPayload объект, который позволяет получить необработанный JSON токена. Это зависит от вашего сценария, какой подход наиболее рациональным.

общая (т. е. не конкретная JWT) документация для SecurityTokenHandler класса составляет

http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.securitytokenhandler.aspx

в зависимости от вашего приложения вы можете настроить обработчик JWT в конвейер WIF точно так же, как и любой другой обработчик.

3 образца его в пользе в разных видах применения на

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

вероятно, один будет соответствовать вашим потребностям или, по крайней мере, будет адаптироваться к ним.


мне просто интересно, почему вообще использовать некоторые библиотеки для декодирования и проверки токенов JWT.

закодированный токен JWT может быть создан с помощью следующий псевдокод

var headers = base64URLencode(myHeaders);
var claims = base64URLencode(myClaims);
var payload = header + "." + claims;

var signature = base64URLencode(HMACSHA256(payload, secret));

var encodedJWT = payload + "." + signature;

это очень легко сделать без какой-либо конкретной библиотеки. Используя следующий код:

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

декодирование токена-это обратная версия кода выше.Для проверки подписи вам нужно будет то же самое и сравнить часть подписи с рассчитанной подпись.

обновление: для тех, как борются, как сделать base64 urlsafe кодирования / декодирования, пожалуйста, смотрите другой поэтому вопрос, а также wiki и RFCs