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


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

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

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

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

2 78

2 ответа:

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

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

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

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

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

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

кроме того,JwtSecurityToken класс имеет дополнительные методы, которые не на базе SecurityToken класс, например a Claims свойство, которое получает содержащиеся утверждения, не проходя через ClaimsIdentity коллекция. Он также имеет Payload свойство, которое возвращает a 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);
    }
}

декодирование маркера-это обратная версия кода above.To проверьте подпись вам нужно будет то же самое и сравнить подпись часть с расчетным подпись.

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