2013-09-07 60 views
64

私はJWTライブラリを使用してJson Webトークンをデコードしており、Microsoftの公式JWT実装System.IdentityModel.Tokens.Jwtに切り替えたいと考えています。System.IdentityModel.Tokens.Jwtを使用してJWTトークンのデコードと検証

ドキュメントは非常に疎であるため、JWTライブラリで何をやっているのかを理解するのは難しいです。 JWTライブラリには、Base64でエンコードされたJWTを取り出し、それをJSONに変換してデシリアライズできるDecodeメソッドがあります。私はSystem.IdentityModel.Tokens.Jwtを使用して同様のことをしたいと思いますが、かなりの量の掘り出した後、どうやって解決するのか分かりません。

GoogleのIDフレームワークで使用するために、JWTトークンをCookieから読み込んでいます。

ご協力いただければ幸いです。

答えて

98

System.IdentityModel.Tokens.SecurityTokenHandlerから派生したJwtSecurityTokenHandlerというクラスがあります。 WIFでは、セキュリティトークンをデシリアライズおよびシリアライズするためのコアクラスです。

クラスには、base64でエンコードされたJWT文字列を取り、JWTを表すSecurityTokenが返されるReadToken(String)メソッドがあります。

SecurityTokenHandlerには、SecurityTokenがあり、ReadOnlyCollection<ClaimsIdentity>が作成されるValidateToken(SecurityToken)メソッドもあります。通常、JWTの場合、元のJWTのプロパティを表す一連の要求を持つ単一のClaimsIdentityオブジェクトが含まれます。

JwtSecurityTokenHandlerは、ValidateTokenのいくつかの追加オーバーロードを定義します。特に、オーバーロードはClaimsPrincipal ValidateToken(JwtSecurityToken, TokenValidationParameters)です。 TokenValidationParameters引数を使用すると、トークン署名証明書(X509SecurityTokensのリスト)を指定できます。また、SecurityTokenではなく、stringとしてJWTを使用するオーバーロードがあります。

これを行うコードはかなり複雑ですが、「ADAL - ネイティブアプリケーションからRESTサービス - ブラウザダイアログを使用したACSによる認証」という名前のGlobal.asax.cxコード(TokenValidationHandlerクラス)あるいは、

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

に位置し、JwtSecurityTokenクラスは、ClaimsIdentityコレクションを介さずに含まれる特許請求の範囲を取得Claims性などの塩基SecurityTokenクラスにない追加のメソッドを有します。 Payloadプロパティもあり、JwtPayloadオブジェクトを返します。このオブジェクトを使用すると、トークンの未処理のJSONを取得できます。それはあなたのシナリオに最も適しているかどうかによって異なります。

一般SecurityTokenHandlerクラスの(すなわち非JWT特定)のドキュメントは、アプリケーションに応じて、

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

であり、あなたは正確に他のハンドラのようなWIFパイプラインにJWTハンドラを設定することができます。

は1つがあなたのニーズをスイートまたは少なくともそれらに適応となり、

おそらく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

でアプリケーションの異なるタイプで使用されていることの3つのサンプルをあります。

+3

私は本当にあなたの答えに感謝するためにどのように苦労している人のために。ですから、ClaimsIdentityを取得したら、それを公開鍵と照合するにはどうすればよいですか?具体的には、自分の公開鍵(https://www.gstatic.com/authtoolkit/cert/gitkit_cert.pem)に対してGoogle IDツールキットJWTを検証しようとしています –

+4

私の答えが更新されました。これで、私はあなたに適切な開発者サンプルの方向を指摘しました。それが役に立てば幸い。 –

+4

@ w.brian - 私は同じことをしようとしています。私はデコードできるトークンと私が検証したい公開鍵を持っていますが、これらのサンプルを見ても私はこれをどうやって行うのか苦労しています。コードが実際にあなたを助けた指針はありますか?ありがとう。 – Barguast

13

JWTトークンのデコードと検証にいくつかのライブラリを使用する理由はまったく不思議です。

エンコードJWTトークンがfollowing pseudocode

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\":\"[email protected]\",\"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コードのバージョンを逆転しています。

UPDATE:どのようにbase64でurlsafeエンコーディング/デコーディングは別のSO question参照してください行い、また、ウィキおよびRFC

+2

良い答え。ここにHMACベースの署名を表示しているので、Auth0サイトで詳しく説明しているように、HMAC検証を実装するライブラリの重大な脆弱性を認識することができます:https://auth0.com/blog/2015/03/31/critical -vulnerabilities-in-json-web-token-libraries/ – dotnetguy

+2

私はこれが最良の答えだと思います。 OPは、JWTに関する情報を要求しました。具体的には、この記事で明確な例を示しています。 – webworm

+6

この回答は、** de **コーディングに関する質問がかなり明確になったときにJWTを** en **コードする方法を説明しています。これは良い答えかもしれませんが、まったく別の質問*への答えです。 – Deltics

関連する問題