Декодирование и проверка токена JWT с помощью системы.IdentityModel.Жетоны.Агентство jwt
Я использую JWT библиотека для декодирования веб-маркера Json и хотела бы переключиться на официальную реализацию JWT от Microsoft,система.IdentityModel.Жетоны.Jwt.
документация очень скудная, поэтому мне трудно понять, как выполнить то, что я делал с библиотекой JWT. С библиотекой JWT существует метод декодирования, который берет кодированный JWT base64 и превращает его в JSON, который затем может быть десериализован. Я хотел бы чтобы сделать что-то подобное с помощью системы.IdentityModel.Жетоны.Jwt, но после изрядного количества копания, не может понять, как это сделать.
для чего это стоит, я читаю токен JWT из файла cookie, для использования с платформой идентификации Google.
любая помощь будет оценили.
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
класс, например aClaims
свойство, которое получает содержащиеся утверждения, не проходя черезClaimsIdentity
коллекция. Он также имеетPayload
свойство, которое возвращает aJwtPayload
объект, который позволяет получить необработанный 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); } }
декодирование маркера-это обратная версия кода above.To проверьте подпись вам нужно будет то же самое и сравнить подпись часть с расчетным подпись.
обновление: для тех, как борются, как сделать base64 urlsafe кодирование / декодирование, пожалуйста, см. Другой поэтому вопрос, а также wiki и RFC