「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>JWTとOAuth2.0#f5007063]] * 目次 [#m5c50d67] #contents *概要 [#a089122f] [[JWT]](JWS) Bearer Tokenを[[アサーション>トークン#xbeb945f]]として使用して、OAuth 2.0のAccess Tokenを要求する方法の定義。 -[[GoogleやMicrosoft、SalesforceなどのWebAPI認証の方式として採用されている>#xd03a507]]。 -事前に信頼関係を構築できるシステムからユーザ承認手順なしに直接WebAPI接続する場合に有効な方法。 -[[RFC 7521, 7523>#c65d5829]]によって構成されている。 *仕様(7521) [#pae256bf] -ClientとResource Serverを統合するような状況下での利用が想定されている。 --Resource Ownerとしてのエンド・ユーザの介入を必要としない。 --client_secretを必要としない(Client Credentialsグラント種別の)代替メカニズム。 **フレームワーク [#v20f3211] ***Assertion Created by Third Party [#vf7e7da7] STSによってアサーションを取得する。 -WS-Trust [OASIS.WS-Trust]などで利用されている。 Relying Party Client Token Service | | | | | 1) Request Assertion | | |------------------------>| | | | | | 2) Assertion | | |<------------------------| | 3) Assertion | | |<-------------------------| | | | | | 4) OK or Failure | | |------------------------->| | | | | | | | ***Self-Issued Assertion [#n8fdd9f7] ローカルでアサーションを作成する。 -[[JWT]](JWS)作成のための証明書を生成 or 取得する。 -証明書を登録する。 --Client側(秘密鍵) --Resource Server側(公開鍵) -Clientで[[JWT]](JWS)を署名/作成し、Resource Serverにリクエスト、 -Resource Serverで[[JWT]](JWS)を検証し、Access Token(Bearer Token)をレスポンス。 -Clientから、Access Token(Bearer Token)を使用してResource Serverにアクセスする。 Relying Party Client | | | | 1) Create | | Assertion | |--------------+ | | | | | 2) Assertion | | |<-------------+ | 3) Assertion | |<-------------------------| | | | 4) OK or Failure | |------------------------->| | | | | *仕様(7523) [#i523cb7d] **[[JWT]](JWS) [#s121ce30] ***ペイロード(クレームセット) [#od912bf1] ***[[JWT]](JWS)の例 [#f5ac0fc6] 以下を、[[アクセストークン・リクエスト>#yf148536]]する。 -ヘッダ { "alg": "RS256", "typ": "JWT" } -ペイロード { "iss":"サービスアカウントのメールアドレス", "scope":"利用するAPIのスコープ", "aud":"https://www.googleapis.com/oauth2/v3/token", "exp":"トークンの有効期限To", "iat":"トークンの有効期限From", } **パラメタ [#jab8a61d] ***grant_type [#c145a29b] urn:ietf:params:oauth:grant-type:jwt-bearer ***assertion [#x8e9da32] [[前述のJWT(JWS)>#s121ce30]] ***scope [#bde37566] -[[[RFC7521]>OAuth#c65d5829]]で定義されているのと同じ。 -従って、scopeはURLではなく、JWSに同梱されて送信される。 **リクエスト・レスポンス [#ne5367ec] ***アクセストークン・リクエスト・レスポンス [#yf148536] -リクエスト --Header POST /token.oauth2 HTTP/1.1 Host: as.example.com Content-Type: application/x-www-form-urlencoded --Body grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer& assertion=...JWS... -レスポンス ***エラー・レスポンス [#n2b1c5ca] { "error":"invalid_grant", "error_description":"Audience validation failed" } *クライアント認証 [#t40d8799] クライアント認証は、オプション **[[JWT]](JWS) [#m2b9aaab] ***ペイロード(クレームセット) [#y39a2162] 以下のClaimが必要だが、[[IDトークン>OpenID Connect#ofb73c59]]が参考になる。 -必須(MUST) --"iss" (issuer) claim --"aud" (audience) claim --"sub" (subject) claim ---許可付与の場合:ユーザIDなど。 ---[[クライアント認証>#t40d8799]]の場合:"client_id" --"exp" (expiration time) claim~ 将来に不当に遠い値を拒否する可能性がある。 -してもよい(MAY) --"iat" (issued at) claim 過去に不当に遠い値を拒否する可能性がある。 --"nbf" (not before) claim ---トークンを受け入れてはならない前の時間を識別する --"jti" (JWT ID) claim ---トークンの一意の識別子を提供する。 ---「exp」の間、「jti」値を維持し、[[JWT]](JWS)が再生されないことを保証する。 [[JWT]](JWS)の署名検証により、認証を行う。 ***[[JWT]](JWS)の例 [#td1d361e] -ヘッダ {"alg": "ES256"、 "kid": "16"} -ペイロード { "iss":"https://jwt-idp.example.com", "sub":"mailto:mike@example.com", "aud":"https://jwt-rp.example.net", "nbf":1300815780, "exp":1300819380, "http://claims.example.com/member":true } **パラメタ [#u6f4e327] -通常のパラメタ --client_id --client_secret -クライアント認証にJWTを使用する場合のパラメタ --client_assertion_type~ urn:ietf:params:oauth:client-assertion-type:jwt-bearer --client_assertion~ 1つの[[JWT]](JWS)、複数の[[JWT]](JWS)を含んではならない。 **リクエスト・レスポンス [#wfe3aa1f] ***認可リクエスト・レスポンス [#t828b5a1] -リクエスト --Header POST /token.oauth2 HTTP/1.1 Host: as.example.com Content-Type: application/x-www-form-urlencoded --Body grant_type=authorization_code& code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4& client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer& client_assertion=...JWS... ***エラー・レスポンス [#u922a3c5] [[OAuth 2.0 [RFC6749]>OAuth#v698197b]]で定義されているエラー応答を構成 -https://tools.ietf.org/html/rfc6749#section-5.2 *参考 [#uea38a81] **RFC 7521, 7522, 7523 [#c65d5829] -RFC 7521 - Assertion Framework for~ OAuth 2.0 Client Authentication and Authorization Grants~ https://tools.ietf.org/html/rfc7521 >[[OAuth]] 2.0 を拡張するアサーションの仕様 -Client Authentication で Client Credentials として使うアサーションの仕様 -Authorization Codeグラント種別のAccess Token と交換するアサーションの仕様 -単体では利用できず、後の2つのサブ仕様の共通部分を抽象化した仕様。 --RFC7522(SAMLアサーション) ---RFC 7522 - Security Assertion Markup Language (SAML) 2.0 Profile~ for OAuth 2.0 Client Authentication and Authorization Grants~ https://tools.ietf.org/html/rfc7522 >JWT を [[RFC 7521(上記)>#e7d6a65b]] の アサーション として利用するための仕様 --RFC7523(JWTアサーション) ---RFC 7523 - JSON Web Token (JWT) Profile~ for OAuth 2.0 Client Authentication and Authorization Grants~ https://tools.ietf.org/html/rfc7523 >JWT を [[RFC 7521(上記)>#e7d6a65b]] の アサーション として利用するための仕様 **用例 [#xd03a507] ***Googleの例 [#pe004c1a] 以下を見ると、 -C#とCoreTweetを使って簡単にTwitterへツイートするbotを作る - 酢ろぐ!~ http://blog.ch3cooh.jp/entry/20140808/1407464147 --Google Analytics API を使って前日の PV を取得するコードを C# で書いてみた - しばやん雑記~ http://blog.shibayan.jp/entry/20140803/1407059293 通常の[[OAuth]] 2.0の -[[Authorization Codeグラント種別>OAuth#yfeb403d]] -[[Implicitグラント種別>OAuth#m5c2d510]] 以外に、 [[クライアント証明書(pfx形式の電子証明書)>証明書#sd119f77]]を使って、~ サービスアカウントで認証する方法がある模様。 ちなみに、ここでは、Google.Apis.Analytics Client Libraryに~ 処理がラッピングされていたため。詳細が不明だったが、 以下を見ると、このClient Libraryの中では、[[JWT]]が使用されている模様。 -JWTを使ってGoogleAPIのアクセストークン取得する - Carpe Diem~ http://christina04.hatenablog.com/entry/2015/06/04/224159 -IdM実験室: [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 これが、 >「JWT bearer token authorizationグラント種別」 の用例である模様。 -GoogleのOAuth 2.0実装からみえたClientの扱い - r-weblife~ http://d.hatena.ne.jp/ritou/20121104/1352036133 上記のサイトには、 >Service Accounts = JWT Bearer Token Profile であることが明記されている。 ***Microsoft ([[AzureAD>Microsoft Azure Active Directory]]) の例 [#vdf678b9] [[Google>#pe004c1a]]と同様に、以下を見ると、 -Azure AD : ログインをしない Backend Server-Side アプリの開発 (Daemon など) – Tsmatz~ https://blogs.msdn.microsoft.com/tsmatsuz/2015/04/09/azure-ad-backend-server-side-deamon-service/ -Azure ADに登録されているAPI用のアクセストークンをJWTで取得するには | hrendoh's memo~ http://blog.hrendoh.com/active-directory-dotnet-daemon-certificate-credential/ --Authenticating to Azure AD in daemon apps with certificates | Microsoft Azure~ https://azure.microsoft.com/ja-jp/resources/samples/active-directory-dotnet-daemon-certificate-credential/ 通常の[[OAuth]] 2.0の -[[Authorization Codeグラント種別>OAuth#yfeb403d]] -[[Implicitグラント種別>OAuth#m5c2d510]] 以外に、 >「JWT bearer token authorizationグラント種別」 をサポートしている模様。 ただし、処理は、[[ADAL(Active Directory Authentication Library)>https://docs.microsoft.com/ja-jp/azure/active-directory/develop/active-directory-authentication-libraries]]~ にラップされているため[[JWT]]作成処理の詳細などを見ることは出来ない。 -active-directory-dotnet-daemon-certificate-credential/Program.cs~ at master · Azure-Samples/active-directory-dotnet-daemon-certificate-credential~ https://github.com/Azure-Samples/active-directory-dotnet-daemon-certificate-credential/blob/master/TodoListDaemonWithCert/Program.cs ***Salesforceの例 [#w40dd954] 以下のQiita記事を参照すると、Salesforceは、 -OAuth 2.0 JWT べアラートークンフロー -OAuth 2.0 SAML ベアラーアサーションフロー の2つのフローをサポートしている模様。 -OAuth2 JWT Bearer Token フローを使ってSalesforceへアクセスする - Qiita~ http://qiita.com/stomita/items/4542ce1b48e5fa849ef1 --help.salesforce. ---OAuth 2.0 JWT べアラートークンフロー~ https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm&language=ja&type=0 ---OAuth 2.0 SAML ベアラーアサーションフロー~ https://help.salesforce.com/articleView?id=remoteaccess_oauth_SAML_bearer_flow.htm&language=ja&type=0 >原理はほぼ同じで、[[SAML]]より[[JWT]]のほうが動作環境的な制約は少ないとのこと。 ---- Tags: [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]