Декодирование и проверка токена 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 образца его в пользе в разных видах применения на
вероятно, один будет соответствовать вашим потребностям или, по крайней мере, будет адаптироваться к ним.
мне просто интересно, почему вообще использовать некоторые библиотеки для декодирования и проверки токенов 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