「[[マイクロソフト系技術情報 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グラント種別の)代替メカニズム。
-クライアント認証はオプション([[用例>#xd03a507]]ではクライアント認証を使用していないケースが多い)。

**フレームワーク [#v20f3211]

***Assertion Created by Third Party [#vf7e7da7]
STSによってアサーションを取得する。

-フロー
     Relying
     Party                     Client                   Token Service
       |                          |                         |
       |                          |  1) Request Assertion   |
       |                          |------------------------>|
       |                          |                         |
       |                          |  2) Assertion           |
       |                          |<------------------------|
       |    3) Assertion          |                         |
       |<-------------------------|                         |
       |                          |                         |
       |    4) OK or Failure      |                         |
       |------------------------->|                         |
       |                          |                         |
       |                          |                         |

-WS-Trust [OASIS.WS-Trust]などで利用されている。

***Self-Issued Assertion [#n8fdd9f7]
ローカルでアサーションを作成する。

-フロー
     Relying
     Party                     Client
       |                          |
       |                          | 1) Create
       |                          |    Assertion
       |                          |--------------+
       |                          |              |
       |                          | 2) Assertion |
       |                          |<-------------+
       |    3) Assertion          |
       |<-------------------------|
       |                          |
       |    4) OK or Failure      |
       |------------------------->|
       |                          |
       |                          |


-JWT bearer token authorizationグラント種別の場合
--[[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にアクセスする。

**アサーションのタイプ [#h0cefaa0]
***Bearer Assertions [#r8dc51ed]
-本使用に適したタイプのアサーション
-アサーションを所有しているすべてのエンティティは、
--関連するリソースへのアクセスを取得するために(暗号鍵の所持を証明することなく)アサーションを使用できる。
--誤用を防止するために、アサーションは、保管・移送における露見から保護する必要がある。
--権限のない当事者にアサーションを漏らさないために、安全な通信チャネルを使用。

***Holder-of-Key Assertions [#r5984214]
-本使用に適さないタイプのアサーション

-アサーションを提示するエンティティは、
--関連するリソースにアクセスするには、追加の暗号資料の所持を証明する必要がある。
--したがって、
---Authorization Server(STS)は、アサーションにキー識別子をバインドする。
---Clientは、アサーションを提示するときに、~
その識別子に対応するキーを知っていることをResource Serverに示す必要がある。

-鍵所有者アサーションシステムのベースラインとして使用することができるが、場合によっては、以下が必要になる。
--(秘密鍵の所有証明をサポートするための)追加のメカニズム
--セキュリティモデルの変更(例えば、 オーディエンスの要件を緩和するため)。

**この文脈上でのアサーション [#i1c8aa27]

-Authorization Serversは、
--一般的に認可付与の短命表現で、アサーションの有効期間を越えるアクセストークンを発行すべきでない。
--アサーション許可要求に応答して
---リフレッシュトークンが発行せず、
---アクセストークンを短い寿命で発行する。

-Clientは、
--同じアサーションを使用して新しいアサーションを要求したり、
--有効・若しくは新しいアサーションを使用して、期限切れのアクセストークンをリフレッシュしたり、

>できる。

**パラメタ [#aed15519]
-TLS(Transport Layer Security)が必須。
-アサーションの認可付与としての使用を定義。

***grant_type [#eef72461]
-クライアント認証なし~
urn:ietf:params:oauth:grant-type:*
--urn:ietf:params:oauth:grant-type:saml2-bearer
--urn:ietf:params:oauth:grant-type:jwt-bearer

-クライアント認証あり
--grant_type=authorization_code
--code=XXXX(authorization_codeなのでcodeも必要)

***assertion [#k4e1e004]
RFC7523を参照。

***scope [#x0b3b1ff]
要求された範囲は、[[OAuth 2.0 [RFC6749]>OAuth#v698197b]]の3.3節に記述されているとおり。

***client_id [#c3be6c2e]
-クライアント認証なし~
パラメタに依存するクライアント認証の形式が使用されている場合にのみ必要

-クライアント認証あり~
クライアント認証がある場合、クライアントがアサーションで識別されるため不要

***client_assertion_type [#y8e7d02b]
-クライアント認証なし~
不要

-クライアント認証あり~
urn:ietf:params:oauth:grant-type:*
--urn:ietf:params:oauth:grant-type:saml2-bearer
--urn:ietf:params:oauth:grant-type:jwt-bearer

***client_assertion [#d6680711]
-クライアント認証なし~
不要

-クライアント認証あり~
RFC7523を参照。

**リクエスト・レスポンス [#u7d06247]
***アクセストークン・リクエスト [#a82c2f7a]
-クライアント認証なし
--ヘッダ
 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded
--ボディ
 grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3AX-bearer&
 assertion=SAML2 or JWT assertion

-クライアント認証あり~
何故か、grant_type=authorization_codeになる。
--ヘッダ
 POST /token HTTP/1.1
 Host: server.example.com
 Content-Type: application/x-www-form-urlencoded
--ボディ
 grant_type=authorization_code&
 code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&
 client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3AX-bearer&
 client_assertion=SAML2 or JWT assertion

***エラー・レスポンス [#u137f3a9]
-[[OAuth 2.0 [RFC6749]>OAuth#v698197b]]で定義されているエラー応答を構成

--https://tools.ietf.org/html/rfc6749#section-5.2

-クライアント認証なし~
アサーションが有効でないか期限が切れた場合、
--Authorization Serverは、 
---"error"パラメータの値は "invalid_grant"エラーコードでなければならない。
---"error_description"または "error_uri"パラメータを使用して、~
アサーションが無効とみなされた理由に関する追加情報を含めることができる。

--例
---ヘッダ
 HTTP/1.1 400 Bad Request
 Content-Type: application/json
 Cache-Control: no-store
---ボディ
 {
  "error":"invalid_grant",
  "error_description":"Audience validation failed"
 }

-クライアント認証あり
--Authorization Serverは、 ~
アサーションが有効でないか複数のクライアント認証メカニズムが使用されている場合、
---"error"パラメータの値は "invalid_client"エラーコードでなければならない。
---"error_description"または "error_uri"パラメータを使用して、~
クライアントのアサーションが無効であると考えられた理由に関する追加情報を含めることができる。

--例
---ヘッダ
 HTTP/1.1 400 Bad Request
 Content-Type: application/json
 Cache-Control: no-store
---ボディ
 {
  "error":"invalid_client"
  "error_description":"assertion has expired"
 }

*仕様(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]
-リクエスト
--ヘッダ
 POST /token.oauth2 HTTP/1.1
 Host: as.example.com
 Content-Type: application/x-www-form-urlencoded
--ボディ
 grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&
 assertion=...JWS...

-レスポンス

***エラー・レスポンス [#n2b1c5ca]


*クライアント認証 [#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]
-リクエスト
--ヘッダ
 POST /token.oauth2 HTTP/1.1
 Host: as.example.com
 Content-Type: application/x-www-form-urlencoded
--ボディ
 grant_type=authorization_code&
 code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&
 client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&
 client_assertion=...JWS...

***エラー・レスポンス [#u922a3c5]

*参考 [#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]]

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS