+ 作るログイン
図を読み込んでいます…
1 / 8
図でつながる 認証と暗号の基礎 / 全9章

OAuth ― パスワードを渡さず、アクセスを委ねる

発行
アニメモ公式
版
第2版
改訂
コマ
全8

コードフローとPKCEを8コマで。認可コード・アクセストークン・リフレッシュトークンの行き先を追います。

写真を読ませたい。パスワードは渡したくない

アオイさんは、写真サービスの写真を印刷アプリで使いたいと考えています。印刷アプリへ写真サービスのパスワードを渡すと、必要以上の力を与えてしまいます。

OAuthは、アプリへ限定したアクセスを委ねるための仕組みです。利用者、アクセスを必要とするクライアント、許可を扱う認可サーバー、データを返すリソースサーバーが登場します。RFC 6749

この教材はOAuth 2.0のAuthorization Code FlowにPKCEを組み合わせた例です。すべてのOAuthフローで人が同意画面を操作するわけではありません。

  • 07 / SECURITY NOTES
  • 1 / 8
  • パスワードを渡さず、アクセスを委ねる
  • 利用者:アオイ
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • 写真を読みたい
  • アプリにパスワードを預けない
  • 利用者・クライアント・認可サーバー・APIが登場する。

アプリは、必要な範囲を添えて認可を依頼する

印刷アプリはブラウザを認可サーバーへ向けます。主な情報は、アプリの識別子 client_id、戻り先 redirect_uri、求める範囲 scope、response_type=code です。

この例では scope=photos:read を求めます。スコープ名は教材用の独自例で、すべてのサービスで共通の名前ではありません。

PKCEでは、アプリがランダムな code_verifier を保持し、そこから作った code_challenge をこのリクエストに付けます。図のchallengeのカードは、後で照合するための値です。PKCE

  • 07 / SECURITY NOTES
  • 2 / 8
  • 必要な範囲とPKCEを添えて依頼
  • 利用者のブラウザ
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • scope: photos:read
  • verifierは保持
  • code_challenge
  • scopeと戻り先を指定し、verifierはアプリが保持する。

利用者は、提供元でログインし範囲を確認する

アオイさんは認可サーバー側でログインし、この例では写真の読み取りを許可します。パスワードを入力する先は写真サービス側であり、印刷アプリではありません。

認可サーバーは利用者やポリシーに基づいて許可を判断します。既存の同意などにより、毎回同意画面が出るとは限りません。

図ではアオイさんの許可が認可サーバーへ届きます。この段階では、印刷アプリが自由に使えるアクセストークンはまだ受け取っていません。

  • 07 / SECURITY NOTES
  • 3 / 8
  • 提供元でログインし、範囲を許可
  • 利用者のブラウザ
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • scope: photos:read
  • 写真の読み取りを許可
  • この例では利用者が許可。アクセストークンはまだない。

ブラウザへ返すのは、短命の認可コード

認可サーバーは、登録・検証された戻り先へブラウザを戻し、認可コードを渡します。コードは短命で一度だけ交換するための値です。APIを呼ぶアクセストークンとは別物です。

図の紫のコードが印刷アプリへ戻ってきます。クライアントは、開始したリクエストとの対応も確認します。state などによるCSRF対策を、採用する仕様に従って実施します。

戻り先の厳密な検査やPKCEなどは現在の重要な防御策です。OAuthのセキュリティ指針

  • 07 / SECURITY NOTES
  • 4 / 8
  • 短命の認可コードで、アプリへ戻る
  • 利用者のブラウザ
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • 認可コード
  • 検証済みの redirect_uri へ
  • 認可コードは交換用。APIを呼ぶトークンではない。

コードとverifierを、トークンエンドポイントへ

印刷アプリは認可コードと code_verifier を、TLSで保護されたトークンエンドポイントへ送ります。認可サーバーは、最初の code_challenge と対応するかなどを確認します。

S256では、verifierのSHA-256をBase64urlで表現した値がchallengeになります。コードだけを盗んだ者が、verifierなしで交換するのを防ぐ仕組みです。

PKCEはクライアント認証の代わりではありません。 サーバーアプリなどの機密クライアントでは、必要なクライアント認証も行います。RFC 7636

  • 07 / SECURITY NOTES
  • 5 / 8
  • コードとverifierを交換する
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • 認可コード
  • code_verifier
  • アクセストークン
  • ← 検証後に発行
  • PKCEを照合し、必要なクライアント認証も行う。

アクセストークンを受け取り、APIへ持っていく

検証を通過すると、印刷アプリはアクセストークンを受け取ります。今度はこのトークンを写真APIへ提示します。図では緑のカードが認可サーバーからアプリへ、次のページでAPIへ移動します。

アクセストークンの見た目はJWTとは限りません。受け手が内容を直接読む形式も、サーバーに照会して意味を得る不透明な値もあります。

リフレッシュトークンが発行される場合は、新しいアクセストークンを得るために使います。写真APIへ持っていくものではありません。トークンの役割

  • 07 / SECURITY NOTES
  • 6 / 8
  • アプリがアクセストークンを受け取る
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • アクセストークン
  • refresh token は再発行用
  • アクセストークンはJWTとは限らない。

APIが、対象と操作を判定する

写真APIはトークンの有効性・対象・許可範囲などを確認し、許される写真を返します。「読み取り」は許可しても、「削除」まで許可したことにはなりません。

GET /photos       → photos:read の範囲で判定
DELETE /photos/42 → 読み取り権限だけでは拒否

これは説明用のAPIです。実際の権限モデルは提供元の仕様に従います。ユーザーの所有物や組織の境界など、対象単位の認可も必要です。

アクセストークンを得たことで、アプリが任意の操作をできるわけではありません。

  • 07 / SECURITY NOTES
  • 7 / 8
  • APIが、許可された操作だけを通す
  • 印刷アプリ
  • 認可サーバー
  • 写真API
  • CLIENT
  • AUTHORIZATION
  • RESOURCE
  • アクセストークン
  • 写真を読む → 許可
  • 写真を消す → 拒否
  • 読み取りを許可しても、削除まで許可したことにはならない。

確認:OAuthのアクセストークンがあればログイン完了?

答えはOAuthだけからは、アプリ向けの標準的な認証結果が決まらないです。OAuthの中心はアクセスの委譲で、利用者の認証結果を標準の形で受け取る仕事はOIDCが補います。

図の三種類を振り返りましょう。認可コードは交換用、アクセストークンはAPIへのアクセス用、リフレッシュトークンは再発行用です。

新しい利用者向けフローを考えるときは、PKCEを備えたコードフローと現在のセキュリティ指針を出発点にします。パスワードをアプリへ預ける方式は使いません。RFC 9700

  • 07 / SECURITY NOTES
  • 8 / 8
  • 確認:どの値を、どこへ渡す?
  • 認可コード
  • アクセストークン
  • リフレッシュ
  • トークンへの交換用
  • APIへ提示
  • 新しいトークンを得る
  • アプリへ認証結果を伝えるなら OIDC
  • OAuthはアクセスの委譲。標準の認証結果はOIDCへ。

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]