使用System.IdentityModel.Tokens.Jwt解码和validationJWT令牌
我一直在使用JWT库来解码一个Json Web Token,并且想切换到微软官方的JWT实现System.IdentityModel.Tokens.Jwt 。
文档非常稀less,所以我很难想出如何完成我在JWT库中所做的工作。 使用JWT库,有一个Decode方法,它将base64编码的JWT转换成可以反序列化的JSON。 我想使用System.IdentityModel.Tokens.Jwt做类似的事情,但经过相当数量的挖掘,不知道如何。
对于它的价值,我正在从cookie中读取JWT令牌,以便与Google的身份框架一起使用。
任何帮助,将不胜感激。
在包里有一个叫做JwtSecurityTokenHandler
的类,它来自System.IdentityModel.Tokens.SecurityTokenHandler
。 在WIF中,这是反序列化和序列化安全令牌的核心类。
该类有一个ReadToken(String)
方法,它将采用base64编码的JWTstring并返回一个代表JWT的SecurityToken
。
SecurityTokenHandler
也有一个ValidateToken(SecurityToken)
方法,它接受你的SecurityToken
并创build一个ReadOnlyCollection<ClaimsIdentity>
。 通常对于JWT,这将包含一个ClaimsIdentity
对象,该对象具有一组代表原始JWT属性的声明。
JwtSecurityTokenHandler
为ValidateToken
定义了一些额外的重载,特别是它有一个ClaimsPrincipal ValidateToken(JwtSecurityToken, TokenValidationParameters)
重载。 TokenValidationParameters
参数允许您指定令牌签名证书(作为X509SecurityTokens
的列表)。 它也有一个重载,把JWT作为一个string
而不是一个SecurityToken
。
执行此操作的代码相当复杂,但可以在开发人员示例中的Global.asax.cx代码( TokenValidationHandler
类)中find,名为“ADAL – 本地应用程序到REST服务 – 通过浏览器对话框进行ACS身份validation”,位于
http://code.msdn.microsoft.com/AAL-Native-App-to-REST-de57f2cc
或者, JwtSecurityToken
类还有其他不属于基本SecurityToken
类的方法,例如Claims
属性,它不通过ClaimsIdentity
集合获取所包含的声明。 它还有一个Payload
属性,它返回一个JwtPayload
对象,它可以让你获得令牌的原始JSON。 这取决于你最适合的scheme。
SecurityTokenHandler
类的通用(即非JWT特定的)文档在
http://msdn.microsoft.com/en-us/library/system.identitymodel.tokens.securitytokenhandler.aspx
根据您的应用程序,您可以像任何其他处理程序一样将JWT处理程序configuration到WIFpipe道中。
有3个样本正在使用在不同types的应用程序
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 =天青%20AD%20Developer%20Experience%20Team
可能会满足您的需求,或者至less可以适应您的需求。
我只是想知道为什么要使用一些库来进行JWT令牌解码和validation。
编码的JWT令牌可以使用以下伪代码创build
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); } }
令牌解码是上述代码的反转版本。为了确定签名,您将需要相同的代码签名部分,并将其与经过计算的签名进行比较。