OAuth 2.0の代表的な利用パターンを仕様から理解しよう - Build Insider https://www.buildinsider.net/enterprise/openid/oauth20
こちらの記事を読んで、まとめた内容を社内勉強会で発表しました。
Client ユースケースで考えるOAuth 2.02019/04/12 Fri. FFTT#352 @tmd45
View Slide
Yoko TAMADA @tmd45Feedforce Inc.ソーシャルPLUS® 開発チーム本業は白魔道士ですHello!2
◉ OpenID TechNight で OpenID Connect とはなんぞやというのを聞いてきた○ 2015/09/09 社外勉強会参加 ブログ◉ 各プロバイダの認証プロトコル #補足○ 2016/04/27 社内記事(↑で聞いた話)過去の OAuth 系共有実績Ⅰ3
過去の OAuth 系共有実績Ⅱ4◉ OpenID BizDay で金融 API の動向について聞いてきた○ 2017/08/02 社外勉強会参加 ブログ◉ FAPI Security について聞いてきた話○ 2017/08/18 社内勉強会 スライド(↑で聞いた話)
今日のおはなしの主な元ネタ5◉ OAuth 2.0の代表的な利用パターンを仕様から理解しよう○ 2017/07/21 Build INSIDER 連載記事より○ 著者は Nov 氏。ぶっちゃけほぼこの記事の話+α◉ 書籍 『OAuth 徹底入門』○ 2019/01/30 発行, 原著 『OAuth 2 in Action』 2017/03/18
イントロダクションOAuth 2.0 の基本をおさらい6
登場人物7認可サーバー例: account.google.comリソースサーバー例: Calendar APIリソースオーナー例: エンドユーザーOAuth クライアント例: iOS Calendar Appクライアントアクセスを認可するアクセストークンAPI アクセスエンドユーザーの認証トークンの発行・管理トークンを受け入れて実際の API を提供図引用元: https://www.buildinsider.net/enterprise/openid/oauth20
◉ 認可(Authorization, AuthZ)○ OAuth クライアントが必要とするリソースへのアクセスをリソースオーナーに許可してもらう◉ 認証(Authentication, AuthN)○ 取得したリソースをもとにしてOAuth クライアントがリソースオーナーを「 A さんだ」と確証する認可と認証8
◉ 実体(Entity)○ エンドユーザー、人間そのもの○ システムは直接「実体」を認識できない◉ 属性(Identity)○ エンドユーザの ID, 個人情報など、リソース○ システムは属性をもとにして「いまブラウザの前にいるのは A さんである」という確証を得る実体と属性9
◉ ID 連携の場合は認可サーバとは別にユーザを管理する第5の登場人物が加わる◉ そのため OAuth 2.0 を拡張した仕様(OpenIDConnect)が必要となる○ OpenID Connectは「OAuth 2.0 にどのような機能を追加すればセキュアな ID 連携が可能となるのか」という視点で策定された仕様ID 連携10
登場人物11認可サーバー例: account.google.comリソースサーバー例: Calendar APIOAuth クライアント例: iOS Calendar Appリソースオーナー例: エンドユーザークライアントアクセスを認可するアクセストークンAPI アクセスエンドユーザーの認証トークンの発行・管理トークンを受け入れて実際の API を提供OAuth クライアントバックエンドクライアント独自のユーザ管理
◉ OAuth 2.0 ユースケースの多様性○ いくつかの Grant Type の必要性 (Grant: リソースオーナーによる許可)■ Authorization Code Grant■ Implicit Grant (Implicit: 暗黙の, 無条件の, 疑わない)■ Resource Owner Password Credentials■ Client Credentials■ Hybrid Grant (OpenID Connect 策定段階に OAuth 2.0 の拡張仕様として定義された)閑話休題12
登場人物の多様性13認可サーバー例: account.google.comリソースサーバー例: Calendar APIリソースオーナー例: エンドユーザーOAuth クライアント例: iOS Calendar Appクライアントアクセスを認可するアクセストークンAPI アクセスエンドユーザーの認証トークンの発行・管理トークンを受け入れて実際の API を提供たいてい人間たいてい Web サーバ上で動作するサービス
登場人物の多様性14認可サーバー例: account.google.comリソースサーバー例: Calendar APIリソースオーナー例: エンドユーザーOAuth クライアント例: iOS Calendar Appクライアントアクセスを認可するアクセストークンAPI アクセスエンドユーザーの認証トークンの発行・管理トークンを受け入れて実際の API を提供たいてい人間それほど多様ではないたいてい Web サーバ上で動作するサービスそれほど多様ではない多種多様↓OAuthユースケースの多様性
OAuth 2.0ユースケースユースケースによって何が違うのか15
◉ OAuth クライアントの特性によって分かれる○ サーバーサイドで動作する Web アプリ○ JS アプリ(アプリ独自バックエンドなし)○ JS アプリ(アプリ独自バックエンドあり)○ ネイティブアプリ(アプリ独自バックエンドなし)○ ネイティブアプリ(アプリ独自バックエンドあり)主なユースケース16
認可サーバー例: account.google.comユーザ認証とクライアント認証17リソースオーナー例: エンドユーザー OAuth クライアント例: iOS Calendar Appユーザー認証: User ID / Passwordクライアント認証: App ID / Secretユーザー認証
◉ secret を秘匿に保てる(Confidential Client)○ サーバーへの不正侵入などがない限り安全○ クライアント認証が行える◉ (あとで実行されるバッチ処理など)比較的長期間有効な API アクセス権限を必要とする◉ クライアントが認証されているので、発行されるアクセストークンの有効期限を伸ばしたり、リフレッシュトークンを使えるようにしたり、利用できる Permission を多くしたりしても安心Web アプリ18もっとも基本となるOAuth 2.0 ユースケース
◉ secret を秘匿に保てない (Public Client)○ クライアント認証が行えない◉ 常にユーザーがブラウザーの前にいることが期待できるため必要に応じて API アクセス権限を再取得可能◉ ブラウザは特定ユーザーと1対1でひも付くことが想定されるためユーザー認証の重要性は低い◉ 取得した Access Token を使って API アクセスを行うのはJS アプリ自身のみJS アプリ(独自バックエンドなし)19
◉ secret を秘匿に保てない(Public Client)○ クライアント認証が行えない◉ 常にユーザーがブラウザーの前にいることが期待できるため必要に応じて API アクセス権限を再取得可能◉ バックエンド側でユーザーのデータを管理しているためバックグラウンドではユーザー認証が必要◉ "ID 連携" に該当するため OAuth 2.0 ケースの範囲外※JS アプリ(独自バックエンドあり)20
◉ secret を秘匿に保てない(Public Client)○ クライアント認証が行えない◉ 初回起動時以外はログインさせることもないので長期間有効な API アクセス権限を必要とする◉ 端末は特定ユーザーと 1対1 で紐付くことが想定されるためユーザー認証の重要性は低い◉ 取得した Access Token を使って API アクセスを行うのはネイティブアプリ自身のみネイティブアプリ(独自バックエンドなし)21
◉ secret を秘匿に保てない(Public Client)○ クライアント認証が行えない◉ 初回起動時以外はログインさせることもないので長期間有効な API アクセス権限を必要とする◉ バックエンド側でユーザーのデータを管理しているためバックグラウンドではユーザー認証が必要◉ "ID 連携" に該当するため OAuth 2.0 ケースの範囲外※ネイティブアプリ(独自バックエンドあり)22
OAuth 2.0利用パターンユースケースに適したフローを知る23
◉ Authorization Code Flow (RFC 6749 - Section 4.1)○ クライアント認証を行うフロー■ Token Request 時に client_secret の指定を行わなければならない(MUST)(RFC 6749 - Section 2.3, 3.2.1)Web アプリ24もっとも基本となるOAuth 2.0 ユースケース
◉ Implicit Flow (RFC 6749 - Section 4.2)○ クライアント認証を行わないフロー○ Authorization Code は利用せず、Authorization Response(ログイン・同意後のコールバック)で直接アクセストークンが返される○ クライアントの身元を保証する手段は redirect_uri しかない○ アクセストークンの有効期限が切れたら再認可してもらえばよい(長期間の API アクセス権限が不要)JS アプリ(独自バックエンドなし)25
◉ Implicit Flow を利用するケース○ クライアントの身元を保証する手段は redirect_uri しかない○ redirect_uri が他のアプリに乗っ取られてしまうようなケースでは Access Token が容易に第三者に漏えいする■ 第三者のアプリに利用されてしまうリスクをはらんでいる iOS/Android の Custom Schema URL の利用にはリスクを伴うネイティブアプリ(独自バックエンドなし)26
◉ Authorization Code Flow を利用するケース○ 一度ログインしてしまえばそれ以降はずっとログイン状態という UX を保つために、継続的に API アクセスが必要なアプリの場合、長期間有効なアクセストークンが必要○ Access Token の有効期限は短いが、Refresh Token の仕組みで適宜新しいアクセストークンを再発行できる○ ただしこの場合でも "クライアント認証を行えない" という特徴は変わらない (RFC 6749 - Section 4.1.3)ネイティブアプリ(独自バックエンドなし)27
◉ Implicit Flow で取得したアクセストークンをバックエンドに送るパターン○ ID 連携のために OAuth 2.0 の仕様から外れるパターン○ 送られてきたアクセストークンが第三者のアプリから投げつけられたものでないことを確認する必要がある (Token 置換攻撃)■ 認証プロバイダによってはこのためのトークン検証 API を用意している○ この場合は拡張された仕様である OpenID Connect を用いることが望ましいJS アプリ / ネイティブアプリ(独自バックエンドあり)28
◉ Hybrid Flow で取得した Authorization Code をバックエンドに送るパターン○ Hybrid Flow は RFC 6749 では定義されていない、OpenIDConnect の策定段階に出てきた OAuth 2.0 の拡張仕様○ アプリで使うための Access Token と、バックエンドに送るための Authorization Code を同時に得る○ バックエンドから認可サーバーへアクセストークンを要求するときにクライアント認証を行うことができるため Token 置換攻撃を意識する必要がないJS アプリ / ネイティブアプリ(独自バックエンドあり)29
◉ OAuth 2.0 の最初の仕様(RFC6749)に含まれていないため、すべての API プラットフォームで利用できるわけではない○ 認可サーバー側がそのフローに対応するかどうか決める○ Facebook や Google は対応している○ response_type=code%20token is HybridHybrid Flow すごーい30
◉ RFC 8252 - OAuth 2.0 for Native Apps October 2017○ Category: Best Current Practice■ 認可リクエストを、外部Webブラウザを経由してのみ行う■ 外部Webブラウザとの連携には基本的に Private-Use URIScheme Redirection を使用する■ WebView や InAppBrowser といった埋め込まれたUserAgent は偽装クライアントの可能性を持つため使用しない■ とかネイティブアプリ向けベストプラクティス31
まとめ結局いろいろあって難しくね?32
◉ ユースケースとパターンは提示されている◉ 適切なパターンを選んで実装しよう○ なんでもかんでも Implicit Flow とかダメよ○ ネイティブアプリとの連携も今や主流○ そもそも認可の範囲を超えてるかも → OpenID Connect◉ それぞれに適切なセキュリティ対策も提示されているので合わせて適用しよう(→ 『OAuth 徹底入門』)ユースケースに合わせたパターンを選ぶ33
Any questions ?You can find me at @tmd45Presentation template by SlidesCarnivalThanks!34
参考: 公式資料35◉ RFC 6749 - The OAuth 2.0 Authorization Framework◉ RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer TokenUsage◉ RFC 6819 - OAuth 2.0 Threat Model and Security Considerations◉ RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients◉ OpenID Foundation Specifications◉ OpenID Foundation Japan 日本語訳 公開資料