MS_OAuth20 - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

OAuth 2.0

概要

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 つ目として追加された。

Authorization Code グラント種別

  • 概要 — Confidential クライアントのサーバ側から使うフロー。

    1. 認証画面で Resource Owner の認証をした後、
    2. 認可エンドポイントの "画面" でリソース・アクセスを認可、
    3. Redirect エンドポイントで仲介コードを取得する。
    4. Token エンドポイントで仲介コードを使用して Access Token と Refresh Token を取得し、
    5. 最後に Access Token を使用して Resource Server にアクセスする。
  • 特徴

    • Authorization Server は Client を認証する。
    • 仲介コード(code)を使用することで、Access Token を User Agent に
      露見させずに処理可能
      。
    • Access Token の露見防止には、Client のエンドポイント・コンテンツの実装に依存する。

Implicit グラント種別

  • 概要 — Public クライアントのクライアント側から使うフロー
    (ただし、サーバ側のエンドポイントは必要)。

    1. 認証画面で Resource Owner の認証をした後、
    2. 認可エンドポイントでリソース・アクセスを認可、Access Token を取得する。
    3. (この間の Redirect で、Access Token が露見する。)
    4. 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 Password Credentials グラント種別

  • 概要 — ベース クライアント セキュリティ モデルみたいなもんだが、
    以下のようにあるため、本グラント種別の利用は、特殊なケースに留める。

    「この認可タイプを使用可能にするときには特に注意を払い、
    他のフローが実行可能でない場合にのみ許可する必要があります。」

    • Resource Owner の Credentials を Client に送る。
    • Client は、それを認可エンドポイントに送る。
    • Client は Access Token を取得して Resource Server にアクセスする。
  • 特徴

    • Resource Owner と Client の間に高い信頼関係があること。
    • 以下のような、特殊なケースに留める。
      • OAuth 2.0 への移行段階。
      • Authorization Code グラント種別のフローを使用できないようなケース。

補足: ROPC は OAuth の存在意義(パスワードを渡さない)を
自ら否定するフロー
である。
しかも Client がパスワードを扱うため、
多要素認証・外部 IdP・パスキーのいずれも使えなくなる。
現在は廃止であり、既存実装があれば移行対象になる。

Client Credentials グラント種別

  • 概要 — サーバ信頼セキュリティ モデルみたいなもん。

    • Client は、Client の Credentials を Token エンドポイントに送る。
    • Client は Access Token を取得して Resource Server にアクセスする。
  • 特徴

    • Client と Authorization Server 間で調整済みの、
      Client の保有するリソースにアクセスする場合に使用する。
    • 従って、Confidential クライアントから使用する。

移行メモ: 元ページは Resource Owner Password Credentials と
Client Credentials の説明で「Credentials を認可エンドポイントに送る」と
していたが、この 2 つのグラント種別は
認可エンドポイントを使わず、Token エンドポイントに直接 POST する
(元ページ自身も後段の「エンドポイントの種類」でそう書いている)。

Clientについて

種類

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)**を要求する。
部分一致を許すと、オープン リダイレクタやサブドメイン乗っ取りと
組み合わせて認可コードを奪取できる。

認可用のCredentials(Token)

Access Token

  • 保護されたリソースにアクセスするために使用される Credential。
  • Authorization Server によって Client に対して発行されるランダムな文字列。
  • アクセス範囲とアクセス期間を表す。発行は Resource Owner によって許可される。
  • Token エンドポイントが発行し、Resource Server への要求に対して次の形式で送信される。
GET /resource/1 HTTP/1.1
Host: example.com
Authorization: Bearer XXXXXXXXXX

Refresh Token

  • Access Token の無効化・期限切れの際に新しい Access Token を取得するための Credential。
  • Refresh Token の発行はオプション。
  • Access Token と異なり、Resource Server に送信されることはない。

認証用のCredentials

  • 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 を使用する(非推奨)。

エンドポイントの種類

URL は仕様で規定されない。

Authorization Server 上のエンドポイント

エンドポイント 概要 特徴
認可エンドポイント Resource Owner を認可する。認証画面ではない(認証結果を見て認可する)。仲介コードや Access Token を発行する HTTPS の GET。Authorization Code / Implicit で使用
Token エンドポイント Access Token・Refresh Token を発行する HTTPS の POST。Implicit を除く全グラント種別で使用

Client 上のエンドポイント(Redirect エンドポイント)

  • 概要 — エンドポイント・コンテンツを返す。HTTPS の GET を使用する。
  • 注意点
    • Authorization Code では、なるべくエンドポイント・コンテンツに
      Token が露見しないようにする。
    • Implicit グラントなど、Token がコンテンツに露見してしまう場合、
      以下に従い拡散を防止する。
      • コンテンツには、3rd party の script を含めるべきでない。
      • Client 自身の script が初回に実行されるようにすること。
      • URI から Token を抽出し、露見しないように他へ POST し Body に含めるなどする。

Requestパラメタ

response_type

認可エンドポイントに GET で送付する。

# グラント種別 パラメタ値 意味
1 Authorization Code code 仲介コードを要求
2 Implicit token Access Token を要求

client_id, client_secret

Client の識別や認証のために、色々な所で使用されるパラメタ。

エンドポイント 用途
認可エンドポイント client_id と redirect_uri の対応をチェックする
Redirect エンドポイント 次の Token エンドポイントに渡す
Token エンドポイント Client の認証を行なう

redirect_uri

client_id に対応する Redirect エンドポイントを指定するためのパラメタ。

  • 認可エンドポイントに GET を送付するときに、絶対パスで指定する。
  • 指定した際は、Token エンドポイントまで引き継がれチェックに使用される。
    認可エンドポイントに渡した値と同じであることを確認する必要がある。

grant_type

Token エンドポイントに POST を送付するときに指定するパラメタ。

# グラント種別 パラメタ値
1 Authorization Code authorization_code
2 Resource Owner Password Credentials password
3 Client Credentials client_credentials
4 上記で Refresh トークンを使用する際 refresh_token

scope

  • Authorization Code / Implicit — 認可エンドポイントに GET で送付する。
    送信前に、画面で認可 scope を Resource Owner に提示する。
  • ROPC / Client Credentials — Token エンドポイントに POST で送付する。
  • 異なる scope の Access Token を発行した場合、Response に scope パラメタを付与する。

state

CSRF のセキュリティ対策に使用が推奨されるパラメタ。

  • 認可エンドポイントに GET を送付するときに指定する。

  • 以降のやり取りでも引き継がれて使用される(値は変更しないこと)。

  • 要件 — 推測困難な文字列である必要がある。(ワンタイム性は必須ではない)

  • 参考

補足: state は「このコールバックは、自分が始めたフローの続きか」を
確かめるためのもの。省略するとログイン CSRF(攻撃者のアカウントに
被害者を紐づける)が成立する。
PKCE は別目的(コード横取り対策)なので、
両方必要である(OAuth 2.1 では PKCE が必須、
state は遷移先の保持と CSRF 対策に引き続き使う)。

Request & Response の例

GET /authorize?response_type=code&client_id=XXXX&state=YYYY
    &redirect_uri=http... HTTP/1.1
Host: ...

参考

内部リンク


Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth

⚠️ **GitHub.com Fallback** ⚠️