「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -戻る --[[JSON]] --[[トークン]] --[[クレームベース認証]] * 目次 [#ld8342fd] #contents *概要 [#yfb13271] 以下の内容で最終確認済み。~ https://tools.ietf.org/html/rfc7519 JWT : JSON Web Tokenは、jot(ジョット)と発音する、~ JOSE : JSON Object Signing and Encryptionのサブセット仕様。 **仕様 [#u3914621] -URL中で使用可能な(、url-safeな)、JSONのアサーションを生成するための仕様 -Base64 URL Encodeした[[ヘッダ>#m9c6f99a]]、[[ペイロード(クレームセット)>#m5b94cda]]等を「.」で連結 --このため、url-safeであり、Webでの取り扱いが楽。 --言語毎のライブラリも整っており、自作も相互運用も容易。 -JWTには、[[JWS>#md583102]]や[[JWE>#y75c2692]]がある([[JWK]]は違う)。 **用途 [#s26d45ab] -以下を主張する。 --メッセージ認証コード(MAC)やデジタル署名で完全性保護されていること([[JWS>#md583102]]) --および/または暗号化されていること([[JWE>#y75c2692]]) -暗号化により、鍵で[[ペイロード(クレームセット)>#m5b94cda]]の改ざんチェックが可能(=信頼関係のセマンティクス)。~ この特徴のため、仲介者を伴う(改竄・盗聴の危険性がある)情報のやり取りに利用される。 --主に、認証サーバから返されるトークンに使われる。 --実際、[[OAuth]] 2.0 拡張や[[OpenID Connect]]などで使われている。 *構造 [#ad27d98c] **構成要素 [#q01f4062] 以下の要素から構成される。 ここの詳細は、[[RFC>#t002076b]]を参照。 個別に、 -[[OpenID Connect]] の [[IDトークン(クレーム)>OpenID Connect#ofb73c59]] -[[JWT生成プログラムの作成方法の参考サイト>JWT#e11d0494]] などを参照のこと。 ***ヘッダ [#m9c6f99a] -JOSE : JSON Object Signing and Encryptionヘッダ --署名・検証のために利用するもの。 --電子署名、MAC に関する情報を保持する。 -ヘッダの内容は、3 種に分けられている。 --Registered Header ---RFC 上で仕様化されているヘッダ内容。 ---署名に使うアルゴリズムを示す alg ---公開鍵の在処を示す jku ([[JWK]] Set URL) --Public Header~ 定義可能だが名前の衝突を避けるために IANA に登録するヘッダ内容。 --Private Header~ 衝突するかもしれないから注意が必要なヘッダ内容。 -ヘッダ・パラメタ --typ(オプション)を設定するなら、 ---"JWT" ---"JOSE" : [[JWS>#md583102]]や[[JWE>#y75c2692]]のCompact Serialization ---"JOSE+JSON" : [[JWS>#md583102]]や[[JWE>#y75c2692]]のJSON Serialization ---"application/"接頭辞を省略したMedia Types --cty(オプション)は、構造情報を伝えるために使用される。 ---"JWT" : [[ネストされたJWT>#sb742cbf]]のペイロード ---"application/"接頭辞を省略したMedia Types --ヘッダ・パラメタとして複製されたクレーム~ [[JWE]]のクレームの一部を復号化前に処理方法を決定する目的で使用する。 --ヘッダ・パラメタは、[[JWS>#md583102]]と[[JWE>#y75c2692]]で異なる。 ---[[JWS>#md583102]]の場合、alg, typなど。 { "alg": "HS256", "typ": "JWT"} ---[[JWE>#y75c2692]]の場合、alg, encなど。 {"alg":"RSA-OAEP","enc":"A256GCM"} ***ペイロード(クレームセット) [#m5b94cda] -[[予約済みクレーム>https://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html#ReservedClaimName]]~ 以下すべて、使用は任意 (OPTIONAL)。 |#|キー|説明|h |1|"iss"|Issuer クレーム| |2|"sub"|Subject クレーム| |3|"aud"|Audience クレーム| |4|"exp"|Expiration Time クレーム| |5|"nbf"|Not Before クレーム| |6|"iat"|Issued At クレーム| |7|"jti"|JWT ID クレーム| |8|"typ"|Type クレーム| -パブリック・クレーム --JWTの利用者によって自由に定義できる。 --衝突を避けるために、 ---IANA JSON Web Token Claim Registry に登録するか、 ---耐衝突性を持つ名前空間を含むパブリック名にすべき。 -プライベート・クレーム --JWTの作成者と利用者の合意のものとで、~ 予約済みでもパブリック・クレーム名でもないプライベート・クレーム名を利用可能。 --ただし、衝突の可能性があるため、慎重に使用する必要がある。 -サンプル { "sub": "1234567890", "name": "John Doe", "admin": true } ***その他 [#h6c0fec8] JWTの種類によって様々。 -[[JWS>#md583102]]~ JWS署名 -[[JWE>#y75c2692]]~ ・・・ **JWTの種類 [#j5dabc60] ***[[JWS]] [#md583102] ***[[JWE]] [#y75c2692] ***ネストされたJWT [#sb742cbf] -ペイロード(若しくは平文)として、[[JWS>#md583102]]や[[JWE>#y75c2692]]が使用される。 -署名と暗号化の両方が必要なネストされたJWTの署名と暗号化の順序は、~ プロデューサがメッセージに署名してから結果を暗号化する(従って、署名を暗号化する)。 ***無担保JWT [#d5575bd7] -[[JWS>#md583102]]でも[[JWE>#y75c2692]]でもない、プレーンなJWT(無担保JWT)。 -[[ヘッダ>#m9c6f99a]]内のalgはnone = {“alg”: “none”} 。 -フォーマット([[JWS Compact Serialization>JWS#xe1c18e7]]) --[[ヘッダ>#m9c6f99a]].[[ペイロード(クレームセット)>#m5b94cda]]. -- BASE64URL (UTF-8 (Header)) . BASE64URL (UTF-8 (Claim Set)) . *JWTの作成と検証手順 [#dd514c38] **JWTの作成手順 [#pfa9f0dd] -JWSやJWEの手順に従って作成 -入れ子になったJWTの場合には[[ヘッダ>#m9c6f99a]]の”cty”の値に”JWT”を指定 ***[[JWS>JWS#paf2520a]] [#n6dca050] ***[[JWE>JWE#k0d929b6]] [#e5ba4555] **JWTの検証(復号)手順 [#r8923712] JWSやJWEの手順に従って検証(復号) ***[[JWS>JWS#ib69bb72]] [#ldcecbc0] ***[[JWE>JWE#g7091459]] [#tc2030de] **JWTのアルゴリズム [#f09e77cd] 利用される各アルゴリズムおよびそれらの識別子を定義している仕様 ***[[JWS>JWS#f133bbd2]] [#w51e31db] ***[[JWE>JWE#head797a]] [#f3dfc9c1] *ユースケース [#neb31e45] -http://openid-foundation-japan.github.io/draft-ietf-jose-use-cases-03.ja.html -JSON Web Token の効用 - Qiita~ http://qiita.com/kaiinui/items/21ec7cc8a1130a1a103a -JWTによるJSONに対する電子署名と、そのユースケース | Developers.IO~ http://dev.classmethod.jp/server-side/json-signing-jws-jwt-usecase/ **認証用途 [#yd304024] -JWT(JSON Web Token)を使った認証を試みる | 69log~ https://blog.kazu69.net/2016/07/30/authenticate_with_json_web_token/ -JWTを認証用トークンに使う時に調べたこと - Carpe Diem~ http://christina04.hatenablog.com/entry/2016/06/07/123000 -JWT(Json Web Token)を利用したWebAPIでのCredentialの受け渡しについて | I am mitsuruog~ http://blog.mitsuruog.info/2014/08/jwtjson-web-tokenwebapicredential.html -カスタム・アプリケーションによる認証フローとプログラミング - Build Insider~ http://www.buildinsider.net/web/msidentitydev/03 ***[[OpenID Connect]]のIDトークン [#o5f70766] [[コチラ>OpenID Connect#ofb73c59]]を参照。 ***[[OAuth]] 2.0のアクセストークン [#f9d1b3ca] [[コチラ>OAuthによる外部ログイン(認証)の研究#yf9cec19]]を参照。 ***シングルサインオン(SSO) [#qc19ebd8] -シングルサインオン - Wikipedia~ https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%AA%E3%83%B3 --近年は、SAMLアサーションやJWTアサーション([[OpenID Connect]]の[[IDトークン>OpenID Connect#ofb73c59]])~ によって、クレデンシャル伝えてSSOを実現する方式が一般的になってきている。 -JWTを使った簡易SSOで徐々にシステムをリニューアルしている話~ http://www.slideshare.net/TsuchiKazu/jwt-ssopepabotech --ショップ(Webアプリ)とカート(WebAPI+SPA)を分離し、~ tempストアをサイト間で共有しないで、認証情報を共有するSSOを実現したい。 --JWTにより、以下を跨いだ認証が可能に。 ---サーバー(Webアプリ・WebAPI)間 ---クライアント(ブラウザ)・サーバー(Webアプリ・WebAPI)間 --また、その後の、 ---マイクロサービス化にも対応可能になる。~ サービスの多様化、フロントエンドの多極化 ---認証情報以外の共有したい情報にも利用することができる。~ この場合、[[JWE>#y75c2692]]を使用する可能性がある(HTTPSなら不要だが)。 -JWT(JSON Webトークン)を使用したシングルサインオンの設定 – Zendesk Support~ https://support.zendesk.com/hc/ja/articles/203663816-JWT-JSON-Web%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3-%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%AA%E3%83%B3%E3%81%AE%E8%A8%AD%E5%AE%9A **メール着信確認トークン [#uc4b4ccb] 以下でメール着信確認トークンを使用するようなケースで利用する事で、~ トークンをtempストアに格納して、後に比較するような実装が不要になる。 -アカウント確認(E-mail confirmation) -パスワード・リセット **共有用URL [#w567a950] -OneDriveのファイル・フォルダ共有にも利用されている。 -URLにオブジェクトに対する[[ACL・ACE]]的なモノをJWTアサーションに同梱。 -サービスが認証したユーザがオブジェクトに対するアクセス許可を持っているか、[[ACL・ACE]]から確認する。 -JWT を扱える[[ライブラリ>#n981cbc3]]は沢山ある。 -署名・暗号化は特定用途であれば、1パターン実装すればイイので自作も可能。 -検証・復号化は網羅性を高めることが難しいので、[[ライブラリ>#n981cbc3]]を使用する。 --OpenID Connect の JWT の署名を自力で検証してみると見えてきた公開鍵暗号の実装の話 - Qiita~ http://qiita.com/bobunderson/items/d48f89e2b3e6ad9f9c4c *ライブラリ [#n981cbc3] **様々なライブラリ(相互運用) [#j1232beb] -JSON Web Token の効用 - Qiita~ http://qiita.com/kaiinui/items/21ec7cc8a1130a1a103a -WebCrypto APIでJSON Web Tokenの検証を試してみる - Qiita~ http://qiita.com/tomoyukilabs/items/faa66805a440f4b30cfb |項番|言語|ライブラリのURL|h |0|JavaScript|https://www.w3.org/TR/WebCryptoAPI/| |1|Ruby|https://github.com/nov/json-jwt| |2|Python|https://github.com/rohe/pyjwkest| |3|Java|https://bitbucket.org/nimbusds/nimbus-jose-jwt/wiki/Home| |4|PHP|https://github.com/ritou/php-Akita_JOSE| |5|Perl|https://github.com/xaicron/p5-JSON-WebToken| |6|Objective-C|https://github.com/yourkarma/JWT| |7|.NETなら|[[NuGetからメジャーな奴を入れる。>#r4ac23c8]]| **相性がある模様 [#l9bea68e] ***[[System.IdentityModel.Tokens.JwtSecurityTokenHandler>https://msdn.microsoft.com/ja-jp/library/system.identitymodel.tokens.jwtsecuritytokenhandler.aspx]] [#y171da32] Microsoft Open Technologiesによって開発された、BCL入りしている~ JSON Web Token Handler For the Microsoft .NETというライブラリ。 下記が参考になる。 -IdM実験室~ http://idmlab.eidentity.jp -- [JWT/OAuth]Service Accountを使ってGoogle APIを利用する①, ②~ ---http://idmlab.eidentity.jp/2015/01/jwtoauthservice-accountgoogle-api.html ---http://idmlab.eidentity.jp/2015/01/jwtoauthservice-accountgoogle-api_5.html 上記は、Resource Ownerであるユーザが介在することなく~ ClientがResource ServerのAPIを利用するようなユースケースらしく、~ 以下の様な、grant_typeで、Access Tokenを取得して、WebAPIにアクセスする。 -grant_type:~ http://oauth.net/grant_type/jwt/1.0/bearer --TenantContextID、AppPrincipalId、SymmetricKey を使用して、 --JWTを投げると、Access Tokenが返ってくるflowのgrant_typeらしい。 この時、Googleの秘密鍵のキー長は1024bitだが、~ このライブラリは最低でも2048bitを要求しているため、 >相互運用が不可だったらしい~ (ちなみにVisual Studioが生成するpfxのキー長も1024bitだったりする)。 恐らく、色々なライブラリ間の実装差異で相互運用が難しくなるようなケースがあると思う。~ また、マニュアルもほとんどなく、恐らく[[JWE]]や[[JWK]]に対応していないものと思われる。 ***[[Microsoft.Owin.Security.Jwt.JwtFormat>https://msdn.microsoft.com/ja-jp/library/microsoft.owin.security.jwt.jwtformat.aspx]] [#ib881924] 以下の2メソッドのインターフェイスを確認すると、~ 引数・戻り値に、Microsoft.Owin.Security.AuthenticationTicketが在ったり、~ .NET技術と結合度が高く、相互運用には向かないように見える。 -[[JwtFormat.Protect メソッド>https://msdn.microsoft.com/ja-jp/library/dn450167.aspx]] -[[JwtFormat.Unprotect メソッド>https://msdn.microsoft.com/ja-jp/library/dn450160.aspx]] **検索結果 [#r4ac23c8] -NuGetやWebを検索した所、以下の3ライブラリの利用者が多い。 -其々の評価 --[[Azure AD>Microsoft Azure Active Directory]]公式と言う事もあり、ダウンロード数は、[[System.IdentityModel.Tokens.Jwt>#f8161509]]が優勢。 --GitHubの★の数は[[Jwt.Net>#o8ee7ae2]]が多いが、[[サポート>https://github.com/jwt-dotnet/jwt/tree/master/src/JWT/Algorithms]]しているアルゴリズムが少ない(素人向け)。 --[[JWE]]などのサポートを含み、Nimbus-JOSE-JWT等と互換性のある玄人向けのライブラリは、[[jose-jwt>#q6cee2ca]]。 ***[[jose-jwt]] [#q6cee2ca] ***Jwt.Net [#o8ee7ae2] -NuGet Gallery | JWT~ https://www.nuget.org/packages/JWT/ -jwt-dotnet/jwt https://github.com/jwt-dotnet/jwt >Jwt.Net, a JWT (JSON Web Token) implementation for .NET ***System.IdentityModel.Tokens.Jwt [#f8161509] 上記の、BCL入りしている[[JwtSecurityTokenHandler>#y171da32]]が含まれる名前空間より~ 一つ下の階層のJWT系の追加ライブラリを格納する名前空間であるもよう。~ ※ 名前空間的には、下の階層の方が、上位スタックになるんだなぁ。 必要に応じて、追加でNuGetから取得する必要がある。 -NuGet Gallery | System.IdentityModel.Tokens.Jwt~ https://www.nuget.org/packages/System.IdentityModel.Tokens.Jwt/ -azure-activedirectory-identitymodel-extensions-for-dotnet~ /src/System.IdentityModel.Tokens.Jwt at dev · AzureAD~ https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/tree/dev/src/System.IdentityModel.Tokens.Jwt **自作のJWTライブラリ [#v028206c] 以下を考慮して開発可能。 ***用途 [#b90af93a] -認証など、特定用途の署名・暗号化、検証・復号化レベルであればであれば自作ライブラリで良い。 -正しく署名・暗号化できていれば、他のライブラリでも検証・復号化が可能。 ***相互運用(検証・復号化) [#dfbab710] 他のライブラリでも検証・復号化が可能かどうかは、~ [[JSON Web Tokens - jwt.io>https://jwt.io/]]などの検証サイトを使用して確認すると良い。 ***Base64url Enc/Dec [#n0909b67] このライブラリも必要になる。 -【C#】Base64urlエンコード・デコード - Qiita~ http://qiita.com/hukatama024e/items/b1352cabcd85948511c3 >RFC4648に条件付きでパディング外すなどの難しい処理が~ あるようなので、ライブラリを使用するほうが良いかもしれない~ (Microsoft.Owin.Securityのicrosoft.Owin.Security.DataHandler.Encoderにライブラリがある)。 ***脆弱性 [#j8e0d191] 実装に脆弱性を作らないように注意する。 -JWS 実装時に作りがちな脆弱性パターン - OAuth.jp~ http://oauth.jp/blog/2015/03/16/common-jws-implementation-vulnerability/ ざっくり、 -alg を "none"に改竄された場合、検証でtrueにするな。 -alg を "HMAC-SHA*"に改竄された場合、検証でtrueにするな。 ということらしい。 後者は、 -公開鍵暗号方式 (RSA / ECDSA) から共通鍵暗号方式 (HMAC) に差し替え、 -「公開鍵文字列を共通鍵として利用して」署名を生成することで、 検証でtrueになるJWTを生成できてしまう模様。 特定用途の自作ライブラリであれば、~ 署名と検証のalgは固定にしておくのも良いと考える。 ***参考 [#v386926d] -[[JWSの自作ライブラリ>JWS#a945c75c]] -[[JWEの自作ライブラリ>JWE#a1a37be5]] *参考 [#p90217f2] -JWT Translation #technight~ http://www.slideshare.net/matake/jwt-trans -JWTについて簡単にまとめてみた - hiyosi's blog~ https://hiyosi.tumblr.com/post/70073770678/jwt%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E7%B0%A1%E5%8D%98%E3%81%AB%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E3%81%BF%E3%81%9F -以下の様な話もあるが、提案されているFernetは(今の所)メジャーではない。 --JOSEは、絶対に避けるべき悪い標準規格である | POSTD~ https://postd.cc/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid/ **内部 [#v258f898] ***[[JWS]] [#l8bfa569] ***[[JWE]] [#x0c18773] ***[[JWK]] [#ma4d797b] ***[[JWA]] [#k03a1d47] **RFC [#t002076b] -IETF JOSE WG と OAuth WG から一気に9本の RFC が! - OAuth.jp~ http://oauth.jp/blog/2015/05/20/jose-and-oauth-assertion-rfcs/ ***OAuth WG [#vdd1ecf0] -RFC 7519 - JSON Web Token (JWT)~ https://tools.ietf.org/html/rfc7519 -[[RFC 7521, 7522, 7523>JWT bearer token authorizationグラント種別#c65d5829]] ***JOSE WG [#z5dc6cf2] jose : Javascript Object Signing and Encryption -[[JWS]] -[[JWE]] -[[JWK]] -[[JWA]] -RFC 7520 - Examples of Protecting Content~ Using JSON Object Signing and Encryption (JOSE)~ https://tools.ietf.org/html/rfc7520 ***OpenID ファウンデーション・ジャパン [#n96a7959] -JSON Web Token (JWT) 日本語訳~ https://openid-foundation-japan.github.io/draft-ietf-oauth-json-web-token-11.ja.html -Use Cases and Requirements for JSON Object Signing and Encryption (JOSE)~ http://openid-foundation-japan.github.io/draft-ietf-jose-use-cases-03.ja.html ---- Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:暗号化]]