「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
- OAuth 2.0では「クライアントは1回のリクエストにおいて二つ以上の認証方式を利用してはならない (MUST NOT).」と言われている。
- Tokenエンドポイントで、JWT(JWS) で強化されたクライアント認証を使用して、OAuth 2.0のAccess Tokenを要求する方法を定義。
クライアント認証 †
以下は、既定のクライアント認証が「無い場合」と「有る場合」で場合分けした概要説明。
(既定の)クライアント認証なしの場合 †
- (既定の)クライアント認証を使用しない(別のクライアント認証としてJWT(JWS) を組み込む)。
- 用例にもあるGoogleやMicrosoft、SalesforceなどのWebAPI認証の方式として採用されている。
概要 †
事前に信頼関係を構築できるシステムからユーザによる認証・認可手順なしに直接Access Tokenを取得する。
フロー †
JWT(JWS)作成のための証明書を生成 or 取得する。
- 証明書を登録する。
- Client側(秘密鍵)
- Resource Server(Authorization Server)側(公開鍵)
- ClientでJWT(JWS)を署名し、Resource Server(Authorization Server)にリクエスト、
- Resource Server(Authorization Server)でJWT(JWS)を検証し、Access Tokenをレスポンス。
- Clientから、Access Tokenを使用してResource Server(Authorization Server)にアクセスする。
(既定の)クライアント認証ありの場合 †
概要 †
以下に(既定の)クライアント認証をしてAccess Tokenを取得する。
- 事前に信頼関係を構築できるシステム
- 既存のユーザによる認証・認可フロー
フロー †
- Client Credentialsグラント種別(既存フロー)と併用するユースケース
- Authorization Codeグラント種別(既存フロー)と併用するユースケース
などのユースケースのフローがある。
※ 仕様として定義されているのは、Tokenエンドポイントに対するリクエスト部のみ。
仕様(7521) †
- 単体では利用できず、RFC 7522, 7523のサブ仕様の共通部分を抽象化した仕様。
- ClientとResource Server(Authorization Server)を統合するような状況下での利用が想定されている。
- Resource Ownerとしてのエンド・ユーザの介入を必要としない。
- client_secretを必要としない(Client Credentialsグラント種別の)代替メカニズム。
フレームワーク †
ココとリンクしている。
Assertion Created by Third Party †
こちらも、用例では紹介されていないが、
Authorization Server(STS)によってAssertionを生成する。
Self-Issued Assertion †
ローカルでAssertionを生成する。
アサーション †
これを使ってアクセストークン・リクエストする。
文脈上 †
この文脈上でのアサーションは、
- Authorization Serverは、
- 一般的に認可付与の短命表現で、
アサーションの有効期間を越えるアクセストークンを発行すべきでない。
- アサーション許可要求に応答して
- リフレッシュトークンが発行せず、
- アクセストークンを短い寿命で発行する。
- Clientは、
- 同じアサーションを使用して新しいアサーションを要求したり、
- 有効・若しくは新しいアサーションを使用して、
期限切れのアクセストークンをリフレッシュしたり、
できる。
タイプ †
- Bearer Assertions(持参人切符)
- 本仕様に適したタイプのアサーション
- アサーションを所有しているすべてのエンティティは、
- 関連するリソースへのアクセスを取得するために(暗号鍵の所持を証明することなく)アサーションを使用できる。
- 誤用を防止するために、アサーションは、保管・移送における露見から保護する必要がある。
- 権限のない当事者にアサーションを漏らさないために、安全な通信チャネルを使用。
- Holder-of-Key Assertions(記名式切符)
- 本仕様に適さないタイプのアサーション(確かに仕様名からして ... だったら書くな。と、)
- アサーションを提示するエンティティは、関連するリソースにアクセスするには、追加の暗号資料の所持を証明する必要がある。
- 従って、
- Authorization Server(STS)は、アサーションにキー識別子をバインドする。
- Clientは、アサーションを提示するときに、その識別子に対応するキーを
知っていることをResource Server(Authorization Server)に示す必要がある。
- 鍵所有者アサーションシステムのベースラインとして使用することができるが、場合によっては、以下が必要になる。
- (秘密鍵の所有証明をサポートするための)追加のメカニズム
- セキュリティモデルの変更(例えば、 オーディエンスの要件を緩和するため)。
クレームセット †
以下のクレームが必要。
- sub
Resourceへのアクセス許可を付与する先を決定する。
- aud
Resource Server(Authorization Server)のID = IDトークンのissの値と同じになる。
- Assertion ID
アサーションの一意の識別子。
- 他のエンティティが誤って同じ識別子を割り当てないことを保証しなくてはならない。
- ワンタイム使用アサーションのメッセージ重複排除を必要とする実装によって使用される可能性がある。
署名 †
- 署名またはメッセージ認証コードを生成する
- アルゴリズムは任意(この仕様の範囲外)
パラメタ †
- TLS(Transport Layer Security)が必須。
- アサーションの認可付与としての使用を定義。
grant_type †
- (既定の)クライアント認証なし
urn:ietf:params:oauth:grant-type:*
- urn:ietf:params:oauth:grant-type:saml2-bearer
- urn:ietf:params:oauth:grant-type:jwt-bearer
- (既定の)クライアント認証あり
既存のフローのgrant_typeを使用する。
- grant_type=client_credentials
- grant_type=authorization_code
authorization_codeなので、codeも必要(code=XXXX)
scope †
要求された範囲は、OAuth 2.0 [RFC6749]の3.3節に記述されているとおり。
client_id †
パラメタに依存するクライアント認証の形式が使用されている場合にのみ必要。
assertion †
client_assertion_type †
- (既定の)クライアント認証あり
urn:ietf:params:oauth:grant-type:*
- urn:ietf:params:oauth:grant-type:saml2-bearer
- urn:ietf:params:oauth:grant-type:jwt-bearer
client_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
- grant_type=client_credentials版
- ヘッダ
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
- ボディ
grant_type=client_credentials&
client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3AX-bearer&
client_assertion=SAML2 or JWT assertion
アクセストークン・レスポンス †
仕様中に明記なし。
エラー・レスポンス †
- (既定の)クライアント認証なし
アサーションが有効でないか期限が切れた場合、
- 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"パラメータを使用して、
クライアントのアサーションが無効であると考えられた理由に関する追加情報を含めることができる。
セキュリティに関する考慮事項 †
- その他、
- SSL/TLSを使用する。
- Assertion IDを実装する。
仕様(7523) †
RFC 7521のアサーションにJWT(JWS)アサーションを使用したもの。
JWT(JWS)アサーション †
これを使ってアクセストークン・リクエストする。
ペイロード(クレームセット) †
- 必須(MUST)
- "iss" (issuer) claim
- "aud" (audience) claim
- "sub" (subject) claim
- "exp" (expiration time) claim
- してもよい(MAY)
- "iat" (issued at) claim
- "jti" (JWT ID) claim
= Assertion ID
- "nbf" (not before) claim
トークンを受け入れてはならない前の時間を識別する。
- 以下、RFCのJWT(JWS)
よくよく確認すると、URLはなに?(Scheme?)
- ヘッダ
{"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
}
- 以下、GoogleのJWT(JWS)
よくよく確認すると、subが無かったりする。
- ヘッダ
{
"alg": "RS256",
"typ": "JWT"
}
- ペイロード
{
"iss":"サービスアカウントのメールアドレス",
"scope":"利用するAPIのスコープ",
"aud":"https://www.googleapis.com/oauth2/v3/token",
"exp":"トークンの有効期限To",
"iat":"トークンの有効期限From",
}
パラメタ †
リクエスト・レスポンス †
アクセストークン・リクエスト †
- (既定の)クライアント認証あり
- ヘッダ
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...
アクセストークン・レスポンス †
仕様中に明記がないが、Googleでのレスポンスは以下の通り。
{
"access_token":"XXXXXXXXXX",
"token_type":"bearer",
"expires_in":nnnnn
}
※ ポイント : refresh_tokenを返さない。
エラー・レスポンス †
仕様(7521)のエラー・レスポンスと同じ。
署名アルゴリズム †
本仕様中に記載はないが、コチラを参考にするとイイ。
参考 †
RFC 7521, 7522, 7523 †
用例 †
Googleの例 †
以下を見ると、
通常のOAuth 2.0の
以外に、
クライアント証明書(pfx形式の電子証明書)を使って、
サービスアカウントで認証する方法がある模様。
ちなみに、ここでは、Google.Apis.Analytics Client Libraryに
処理がラッピングされていたため。詳細が不明だったが、
以下を見ると、このClient Libraryの中では、JWTが使用されている模様。
- IdM実験室: [JWT/OAuth]Service Accountを使ってGoogle APIを利用する
これが、
「JWT bearer token authorizationグラント種別」
の用例である模様。
上記のサイトには、
Service Accounts = JWT Bearer Token Profile
であることが明記されている。
Googleと同様に、以下を見ると、
通常のOAuth 2.0の
以外に、
「JWT bearer token authorizationグラント種別」
をサポートしている模様。
ただし、処理は、ADAL(Active Directory Authentication Library)
にラップされているためJWT作成処理の詳細などを見ることは出来ない。
Salesforceの例 †
以下のQiita記事を参照すると、Salesforceは、
- OAuth 2.0 JWT べアラートークンフロー
- OAuth 2.0 SAML ベアラーアサーションフロー
の2つのフローをサポートしている模様。
原理はほぼ同じで、SAMLよりJWTのほうが動作環境的な制約は少ないとのこと。
Tags: :IT国際標準, :認証基盤, :クレームベース認証, :OAuth