MS_OAuth20 - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- 戻る(OAuth)
- OAuth 2.0
- OAuth 1.0
- OAuth 2.1
- OAuth 2.0 拡張
- OpenID Connect
OAuth 2.0 は、認証ではなく認可のためのプロトコル(権限委譲プロトコル)。
- Authorization Server の設置により、Resource Owner と Client を分離することができる。
- これにより、Resource Owner の Credentials を Client に渡す必要が無くなる。
- Resource Owner は、Authorization Server によって、
Client の Resource Server へのアクセスを認可できるようになる。
補足(最重要:認証に使ってはならない): 「認証ではなく認可」という
冒頭の一文が本仕様の最重要事項である。アクセス トークンを受け取れたこと ≠ ユーザーがログインしたこと。
トークンは他所で盗まれたものかもしれず、
しかも「誰のトークンか」を Client が確かめる手段が RFC 6749 には無い。これを悪用するのが「トークン置き換え攻撃」で、
攻撃者が自分のトークンを被害者の Client に渡すと、
Client は攻撃者を被害者と誤認しうる。認証がしたいなら OpenID Connect の
ID トークンを使うこと。
| 役割 | 実体例 | やること |
|---|---|---|
| Resource Owner | ユーザ(人間) | Credentials を入力してリソースにアクセスする |
| Client | Web ブラウザ / スマホ ネイティブ / Web アプリケーション | Authorization Server の認可を受けて Resource Server のリソースにアクセスする |
| Authorization Server | 認証・認可のサーバー機能(Web アプリケーション) | 認証チケットの発行、Access Token の発行 |
| Resource Server | リソースアクセスを提供するサーバー機能(WebAPI など)。Authorization Server と別でも良い | Access Token を受けてリソースアクセスを提供する |
- Client について — 認可レイヤの設置により、認証・認可の役割が分割されたため、
Resource Owner, Authorization Server, Resource Server を繋ぐ
忙しいプログラムになった(だから OAuth は Client 側でも難しい)。
+--------+ +---------------+
| |--(A)- Authorization Request ->| Resource |
| | | Owner |
| |<-(B)-- Authorization Grant ---| |
| | +---------------+
| |
| | +---------------+
| |--(C)-- Authorization Grant -->| Authorization |
| Client | | Server |
| |<-(D)----- Access Token -------| |
| | +---------------+
| |
| | +---------------+
| |--(E)----- Access Token ------>| Resource |
| | | Server |
| |<-(F)--- Protected Resource ---| |
+--------+ +---------------+
| 記号 | 内容 |
|---|---|
| (A) Authorization Request | Resource Owner は、Client を経由して、Authorization Server(の認証画面)で認証する。 |
| (B) Authorization Grant | 認証後、Client は、認可エンドポイントで認可グラントを受け取る。 |
| (C) Authorization Grant | Client は、Token エンドポイントに認可グラントを提示することで、Access Token を要求する。 |
| (D) Access Token | Authorization Server は、Client と認可グラントが正当であれば、Client に Access Token を発行する。 |
| (E)(F) | Client は、Resource Server に Access Token を提示して Protected Resource にアクセスする。 |
以下、4 つのグラント種別に対応するフローがある。
補足(最新化:現在使ってよいのは 2 つだけ): RFC 6749 の 4 種のうち、
2 つは廃止された(OAuth 2.1 / RFC 9700)。
グラント種別 現在 Authorization Code 現役(ただし PKCE 必須) Implicit 廃止 Resource Owner Password Credentials(ROPC) 廃止 Client Credentials 現役(ユーザー不在の系のみ) 加えて、後から Device Authorization Grant(RFC 8628)が
使える 3 つ目として追加された。
-
概要 — Confidential クライアントのサーバ側から使うフロー。
- 認証画面で Resource Owner の認証をした後、
- 認可エンドポイントの "画面" でリソース・アクセスを認可、
- Redirect エンドポイントで仲介コードを取得する。
- Token エンドポイントで仲介コードを使用して Access Token と Refresh Token を取得し、
- 最後に Access Token を使用して Resource Server にアクセスする。
-
特徴
- Authorization Server は Client を認証する。
- 仲介コード(
code)を使用することで、Access Token を User Agent に
露見させずに処理可能。 - Access Token の露見防止には、Client のエンドポイント・コンテンツの実装に依存する。
-
概要 — Public クライアントのクライアント側から使うフロー
(ただし、サーバ側のエンドポイントは必要)。- 認証画面で Resource Owner の認証をした後、
- 認可エンドポイントでリソース・アクセスを認可、Access Token を取得する。
- (この間の Redirect で、Access Token が露見する。)
- Redirect エンドポイントでは、Access Token を Public クライアントに返す。
-
特徴
- Authorization Server は Client を認証しない。
- ラウンドトリップが少なく、応答性に優れる。
- 反面、仲介コードを使用しないため、Access Token が User Agent に
露見するセキュリティのトレードオフがある(RFC 6749 §10.3、§10.16)。
補足: 「トレードオフ」と書かれているが、現在は
割に合わないと結論が出ている。
トークンが URL フラグメントに載る以上、
ブラウザ履歴・Referer・拡張機能・ログから漏れる経路を塞げない。
SPA でも Authorization Code + PKCE を使うこと。
-
概要 — ベース クライアント セキュリティ モデルみたいなもんだが、
以下のようにあるため、本グラント種別の利用は、特殊なケースに留める。「この認可タイプを使用可能にするときには特に注意を払い、
他のフローが実行可能でない場合にのみ許可する必要があります。」- Resource Owner の Credentials を Client に送る。
- Client は、それを認可エンドポイントに送る。
- Client は Access Token を取得して Resource Server にアクセスする。
-
特徴
- Resource Owner と Client の間に高い信頼関係があること。
- 以下のような、特殊なケースに留める。
- OAuth 2.0 への移行段階。
- Authorization Code グラント種別のフローを使用できないようなケース。
補足: ROPC は OAuth の存在意義(パスワードを渡さない)を
自ら否定するフローである。
しかも Client がパスワードを扱うため、
多要素認証・外部 IdP・パスキーのいずれも使えなくなる。
現在は廃止であり、既存実装があれば移行対象になる。
-
概要 — サーバ信頼セキュリティ モデルみたいなもん。
- Client は、Client の Credentials を Token エンドポイントに送る。
- Client は Access Token を取得して Resource Server にアクセスする。
-
特徴
- Client と Authorization Server 間で調整済みの、
Client の保有するリソースにアクセスする場合に使用する。 - 従って、Confidential クライアントから使用する。
- Client と Authorization Server 間で調整済みの、
移行メモ: 元ページは Resource Owner Password Credentials と
Client Credentials の説明で「Credentials を認可エンドポイントに送る」と
していたが、この 2 つのグラント種別は
認可エンドポイントを使わず、Token エンドポイントに直接 POST する
(元ページ自身も後段の「エンドポイントの種類」でそう書いている)。
Client Credentials の機密性保持能力による分類
| 分類 | 内容 | 例 |
|---|---|---|
| Confidential クライアント | Client Credentials の機密性を維持可能 | アクセスの制限されたサーバー、Web アプリケーション |
| Public クライアント | 機密性を維持不可能 | WWW ブラウザ、ネイティブ・アプリケーション、SPA |
- クライアント識別子を使用して、Client を事前登録する。
- Authorization Code や Implicit グラント種別の Redirect エンドポイント
-
client_idに対応する Redirect エンドポイントの URL(絶対パス)を事前登録する。 - 動的設定では部分一致をサポートするが、オープンリダイレクト脆弱性がある。
-
補足(最新化): 「部分一致」は現在禁止である。
RFC 9700 / OAuth 2.1 は
**redirect_uriの完全一致(simple string comparison)**を要求する。
部分一致を許すと、オープン リダイレクタやサブドメイン乗っ取りと
組み合わせて認可コードを奪取できる。
- 保護されたリソースにアクセスするために使用される Credential。
- Authorization Server によって Client に対して発行されるランダムな文字列。
- アクセス範囲とアクセス期間を表す。発行は Resource Owner によって許可される。
- Token エンドポイントが発行し、Resource Server への要求に対して次の形式で送信される。
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer XXXXXXXXXX
- Access Token の無効化・期限切れの際に新しい Access Token を取得するための Credential。
- Refresh Token の発行はオプション。
- Access Token と異なり、Resource Server に送信されることはない。
-
Resource Owner — 認証用の Credentials は OAuth 2.0 仕様の外
(Authorization Server はユーザ ID、パスワードなどを使用して Resource Owner を認証) -
Client — Client の認証用の Credentials
- クライアント識別子(2 つのセット)の情報は、URI で送信しない。
-
client_id(1 つだけの場合、URI に露見する) -
client_secret(URI に露見しない、させない)
-
- 認証方法
- ベーシック認証などのパスワードベースの HTTP 認証スキーム
- HTTP 認証スキームを使用できない場合に POST を使用する(非推奨)。
- クライアント識別子(2 つのセット)の情報は、URI で送信しない。
URL は仕様で規定されない。
| エンドポイント | 概要 | 特徴 |
|---|---|---|
| 認可エンドポイント | Resource Owner を認可する。認証画面ではない(認証結果を見て認可する)。仲介コードや Access Token を発行する | HTTPS の GET。Authorization Code / Implicit で使用 |
| Token エンドポイント | Access Token・Refresh Token を発行する | HTTPS の POST。Implicit を除く全グラント種別で使用 |
- 概要 — エンドポイント・コンテンツを返す。HTTPS の GET を使用する。
- 注意点
- Authorization Code では、なるべくエンドポイント・コンテンツに
Token が露見しないようにする。 - Implicit グラントなど、Token がコンテンツに露見してしまう場合、
以下に従い拡散を防止する。- コンテンツには、3rd party の script を含めるべきでない。
- Client 自身の script が初回に実行されるようにすること。
- URI から Token を抽出し、露見しないように他へ POST し Body に含めるなどする。
- Authorization Code では、なるべくエンドポイント・コンテンツに
認可エンドポイントに GET で送付する。
| # | グラント種別 | パラメタ値 | 意味 |
|---|---|---|---|
| 1 | Authorization Code | code |
仲介コードを要求 |
| 2 | Implicit | token |
Access Token を要求 |
Client の識別や認証のために、色々な所で使用されるパラメタ。
| エンドポイント | 用途 |
|---|---|
| 認可エンドポイント |
client_id と redirect_uri の対応をチェックする |
| Redirect エンドポイント | 次の Token エンドポイントに渡す |
| Token エンドポイント | Client の認証を行なう |
client_id に対応する Redirect エンドポイントを指定するためのパラメタ。
- 認可エンドポイントに GET を送付するときに、絶対パスで指定する。
- 指定した際は、Token エンドポイントまで引き継がれチェックに使用される。
認可エンドポイントに渡した値と同じであることを確認する必要がある。
Token エンドポイントに POST を送付するときに指定するパラメタ。
| # | グラント種別 | パラメタ値 |
|---|---|---|
| 1 | Authorization Code | authorization_code |
| 2 | Resource Owner Password Credentials | password |
| 3 | Client Credentials | client_credentials |
| 4 | 上記で Refresh トークンを使用する際 | refresh_token |
- Authorization Code / Implicit — 認可エンドポイントに GET で送付する。
送信前に、画面で認可 scope を Resource Owner に提示する。 - ROPC / Client Credentials — Token エンドポイントに POST で送付する。
- 異なる scope の Access Token を発行した場合、Response に
scopeパラメタを付与する。
CSRF のセキュリティ対策に使用が推奨されるパラメタ。
-
認可エンドポイントに GET を送付するときに指定する。
-
以降のやり取りでも引き継がれて使用される(値は変更しないこと)。
-
要件 — 推測困難な文字列である必要がある。(ワンタイム性は必須ではない)
-
参考
- OAuth 2.0のstateとredirect_uriとOpenID ConnectのnonceとID Tokenについて - r-weblife
http://d.hatena.ne.jp/ritou/20121008/1349695124 - CSRF対策のトークンをワンタイムにしたら意図に反して脆弱になった実装例 - 徳丸浩の日記
http://www.tokumaru.org/d/20110127.html
- OAuth 2.0のstateとredirect_uriとOpenID ConnectのnonceとID Tokenについて - r-weblife
補足:
stateは「このコールバックは、自分が始めたフローの続きか」を
確かめるためのもの。省略するとログイン CSRF(攻撃者のアカウントに
被害者を紐づける)が成立する。
PKCE は別目的(コード横取り対策)なので、
両方必要である(OAuth 2.1 では PKCE が必須、
stateは遷移先の保持と CSRF 対策に引き続き使う)。
GET /authorize?response_type=code&client_id=XXXX&state=YYYY
&redirect_uri=http... HTTP/1.1
Host: ...
- RFC 6749 - The OAuth 2.0 Authorization Framework
https://datatracker.ietf.org/doc/html/rfc6749\ (日本語訳 http://openid-foundation-japan.github.io/rfc6749.ja.html ) - RFC 6750 - Bearer Token Usage
https://datatracker.ietf.org/doc/html/rfc6750 - RFC 9700 - Best Current Practice for OAuth 2.0 Security
https://datatracker.ietf.org/doc/html/rfc9700
- OAuth 2.0 拡張
- OAuth 2.0 のトークン
- OAuth PKCE
- OAuth 2.0 セキュリティ関連トピック
- 技術文書中での Shall / Should / May
- Microsoft Entra ID(Azure Active Directory)
Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth