『OAuth 2.0 の代表的な利用パターンを仕様から理解しよう』を読んだ話(2019/04/12 FFTT#352)

『OAuth 2.0 の代表的な利用パターンを仕様から理解しよう』を読んだ話(2019/04/12 FFTT#352)

OAuth 2.0の代表的な利用パターンを仕様から理解しよう - Build Insider
https://www.buildinsider.net/enterprise/openid/oauth20

こちらの記事を読んで、まとめた内容を社内勉強会で発表しました。

Fffc4f94bc7b7358b4f0a9663976a19e?s=128

Yoko TAMADA

April 12, 2019
Tweet

Transcript

  1. Client ユースケースで考える OAuth 2.0 2019/04/12 Fri. FFTT#352 @tmd45

  2. Yoko TAMADA @tmd45 Feedforce Inc. ソーシャルPLUS® 開発チーム 本業は白魔道士です Hello! 2

  3. ◉ OpenID TechNight で OpenID Connect とはなんぞやとい うのを聞いてきた ◦ 2015/09/09

    社外勉強会参加 ブログ ◉ 各プロバイダの認証プロトコル #補足 ◦ 2016/04/27 社内記事(↑で聞いた話) 過去の OAuth 系共有実績Ⅰ 3
  4. 過去の OAuth 系共有実績Ⅱ 4 ◉ OpenID BizDay で金融 API の動向について聞いてきた

    ◦ 2017/08/02 社外勉強会参加 ブログ ◉ FAPI Security について聞いてきた話 ◦ 2017/08/18 社内勉強会 スライド(↑で聞いた話)
  5. 今日のおはなしの主な元ネタ 5 ◉ OAuth 2.0の代表的な利用パターンを仕様から理解しよう ◦ 2017/07/21 Build INSIDER 連載記事より

    ◦ 著者は Nov 氏。ぶっちゃけほぼこの記事の話+α ◉ 書籍 『OAuth 徹底入門』 ◦ 2019/01/30 発行, 原著 『OAuth 2 in Action』 2017/03/18
  6. イントロダクション OAuth 2.0 の基本をおさらい 6

  7. 登場人物 7 認可サーバー 例: account.google.com リソースサーバー 例: Calendar API リソースオーナー

    例: エンドユーザー OAuth クライアント 例: iOS Calendar App クライアントアクセス を認可する アクセストークン API アクセス エンドユーザーの認証 トークンの発行・管理 トークンを受け入れて 実際の API を提供 図引用元: https://www.buildinsider.net/enterprise/openid/oauth20
  8. ◉ 認可(Authorization, AuthZ) ◦ OAuth クライアントが必要とするリソースへの アクセスをリソースオーナーに許可してもらう ◉ 認証(Authentication, AuthN)

    ◦ 取得したリソースをもとにしてOAuth クライアントが リソースオーナーを「 A さんだ」と確証する 認可と認証 8
  9. ◉ 実体(Entity) ◦ エンドユーザー、人間そのもの ◦ システムは直接「実体」を認識できない ◉ 属性(Identity) ◦ エンドユーザの

    ID, 個人情報など、リソース ◦ システムは属性をもとにして「いまブラウザの前にいる のは A さんである」という確証を得る 実体と属性 9
  10. ◉ ID 連携の場合は認可サーバとは別にユーザを 管理する第5の登場人物が加わる ◉ そのため OAuth 2.0 を拡張した仕様(OpenID Connect)が必要となる

    ◦ OpenID Connectは「OAuth 2.0 にどのような機能を 追加すればセキュアな ID 連携が可能となるのか」と いう視点で策定された仕様 ID 連携 10
  11. 登場人物 11 認可サーバー 例: account.google.com リソースサーバー 例: Calendar API OAuth

    クライアント 例: iOS Calendar App リソースオーナー 例: エンドユーザー クライアントアクセス を認可する アクセストークン API アクセス エンドユーザーの認証 トークンの発行・管理 トークンを受け入れて 実際の API を提供 OAuth クライアント バックエンド クライアント独自の ユーザ管理
  12. ◉ 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. 登場人物の多様性 13 認可サーバー 例: account.google.com リソースサーバー 例: Calendar API リソースオーナー

    例: エンドユーザー OAuth クライアント 例: iOS Calendar App クライアントアクセス を認可する アクセストークン API アクセス エンドユーザーの認証 トークンの発行・管理 トークンを受け入れて 実際の API を提供 たいてい人間 たいてい Web サーバ上で 動作するサービス
  14. 登場人物の多様性 14 認可サーバー 例: account.google.com リソースサーバー 例: Calendar API リソースオーナー

    例: エンドユーザー OAuth クライアント 例: iOS Calendar App クライアントアクセス を認可する アクセストークン API アクセス エンドユーザーの認証 トークンの発行・管理 トークンを受け入れて 実際の API を提供 たいてい人間 それほど 多様ではない たいてい Web サーバ上で 動作するサービス それほど 多様ではない 多種多様 ↓ OAuth ユースケース の多様性
  15. OAuth 2.0 ユースケース ユースケースによって何が違うのか 15

  16. ◉ OAuth クライアントの特性によって分かれる ◦ サーバーサイドで動作する Web アプリ ◦ JS アプリ(アプリ独自バックエンドなし)

    ◦ JS アプリ(アプリ独自バックエンドあり) ◦ ネイティブアプリ(アプリ独自バックエンドなし) ◦ ネイティブアプリ(アプリ独自バックエンドあり) 主なユースケース 16
  17. 認可サーバー 例: account.google.com ユーザ認証とクライアント認証 17 リソースオーナー 例: エンドユーザー OAuth クライアント

    例: iOS Calendar App ユーザー認証: User ID / Password クライアント認証: App ID / Secret ユーザー認証
  18. ◉ secret を秘匿に保てる(Confidential Client) ◦ サーバーへの不正侵入などがない限り安全 ◦ クライアント認証が行える ◉ (あとで実行されるバッチ処理など)比較的長期間

    有効な API アクセス権限を必要とする ◉ クライアントが認証されているので、発行されるアクセストーク ンの有効期限を伸ばしたり、リフレッシュトークンを使えるよう にしたり、利用できる Permission を多くしたりしても安心 Web アプリ 18 もっとも基本となる OAuth 2.0 ユースケース
  19. ◉ secret を秘匿に保てない (Public Client) ◦ クライアント認証が行えない ◉ 常にユーザーがブラウザーの前にいることが期待できるた め必要に応じて

    API アクセス権限を再取得可能 ◉ ブラウザは特定ユーザーと1対1でひも付くことが想定され るためユーザー認証の重要性は低い ◉ 取得した Access Token を使って API アクセスを行うのは JS アプリ自身のみ JS アプリ(独自バックエンドなし) 19
  20. ◉ secret を秘匿に保てない(Public Client) ◦ クライアント認証が行えない ◉ 常にユーザーがブラウザーの前にいることが期待できるた め必要に応じて API

    アクセス権限を再取得可能 ◉ バックエンド側でユーザーのデータを管理しているため バックグラウンドではユーザー認証が必要 ◉ "ID 連携" に該当するため OAuth 2.0 ケースの範囲外※ JS アプリ(独自バックエンドあり) 20
  21. ◉ secret を秘匿に保てない(Public Client) ◦ クライアント認証が行えない ◉ 初回起動時以外はログインさせることもないので 長期間有効な API

    アクセス権限を必要とする ◉ 端末は特定ユーザーと 1対1 で紐付くことが想定される ためユーザー認証の重要性は低い ◉ 取得した Access Token を使って API アクセスを行うのは ネイティブアプリ自身のみ ネイティブアプリ(独自バックエンドなし) 21
  22. ◉ secret を秘匿に保てない(Public Client) ◦ クライアント認証が行えない ◉ 初回起動時以外はログインさせることもないので 長期間有効な API

    アクセス権限を必要とする ◉ バックエンド側でユーザーのデータを管理しているため バックグラウンドではユーザー認証が必要 ◉ "ID 連携" に該当するため OAuth 2.0 ケースの範囲外※ ネイティブアプリ(独自バックエンドあり) 22
  23. OAuth 2.0 利用パターン ユースケースに適したフローを知る 23

  24. ◉ 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 ユースケース
  25. ◉ Implicit Flow (RFC 6749 - Section 4.2) ◦ クライアント認証を行わないフロー

    ◦ Authorization Code は利用せず、Authorization Response (ログイン・同意後のコールバック)で直接アクセストークンが 返される ◦ クライアントの身元を保証する手段は redirect_uri しかな い ◦ アクセストークンの有効期限が切れたら再認可してもらえば よい(長期間の API アクセス権限が不要) JS アプリ(独自バックエンドなし) 25
  26. ◉ Implicit Flow を利用するケース ◦ クライアントの身元を保証する手段は redirect_uri しかな い ◦

    redirect_uri が他のアプリに乗っ取られてしまうようなケー スでは Access Token が容易に第三者に漏えいする ▪ 第三者のアプリに利用されてしまうリスクをはらんでい る iOS/Android の Custom Schema URL の利用には リスクを伴う ネイティブアプリ(独自バックエンドなし) 26
  27. ◉ Authorization Code Flow を利用するケース ◦ 一度ログインしてしまえばそれ以降はずっとログイン状態と いう UX を保つために、継続的に

    API アクセスが必要なアプ リの場合、長期間有効なアクセストークンが必要 ◦ Access Token の有効期限は短いが、Refresh Token の仕 組みで適宜新しいアクセストークンを再発行できる ◦ ただしこの場合でも "クライアント認証を行えない" という特 徴は変わらない (RFC 6749 - Section 4.1.3) ネイティブアプリ(独自バックエンドなし) 27
  28. ◉ Implicit Flow で取得したアクセストークンをバックエンドに 送るパターン ◦ ID 連携のために OAuth 2.0

    の仕様から外れるパターン ◦ 送られてきたアクセストークンが第三者のアプリから投げつ けられたものでないことを確認する必要がある (Token 置換攻撃) ▪ 認証プロバイダによってはこのためのトークン検証 API を用意 している ◦ この場合は拡張された仕様である OpenID Connect を用い ることが望ましい JS アプリ / ネイティブアプリ(独自バックエンドあり) 28
  29. ◉ Hybrid Flow で取得した Authorization Code をバックエン ドに送るパターン ◦ Hybrid

    Flow は RFC 6749 では定義されていない、OpenID Connect の策定段階に出てきた OAuth 2.0 の拡張仕様 ◦ アプリで使うための Access Token と、バックエンドに送るた めの Authorization Code を同時に得る ◦ バックエンドから認可サーバーへアクセストークンを要求す るときにクライアント認証を行うことができるため Token 置換 攻撃を意識する必要がない JS アプリ / ネイティブアプリ(独自バックエンドあり) 29
  30. ◉ OAuth 2.0 の最初の仕様(RFC6749)に含まれていないた め、すべての API プラットフォームで利用できるわけではな い ◦ 認可サーバー側がそのフローに対応するかどうか決

    める ◦ Facebook や Google は対応している ◦ response_type=code%20token is Hybrid Hybrid Flow すごーい 30
  31. ◉ RFC 8252 - OAuth 2.0 for Native Apps October

    2017 ◦ Category: Best Current Practice ▪ 認可リクエストを、外部Webブラウザを経由してのみ行う ▪ 外部Webブラウザとの連携には基本的に Private-Use URI Scheme Redirection を使用する ▪ WebView や InAppBrowser といった埋め込まれた UserAgent は偽装クライアントの可能性を持つため使用しない ▪ とか ネイティブアプリ向けベストプラクティス 31
  32. まとめ 結局いろいろあって難しくね? 32

  33. ◉ ユースケースとパターンは提示されている ◉ 適切なパターンを選んで実装しよう ◦ なんでもかんでも Implicit Flow とかダメよ ◦

    ネイティブアプリとの連携も今や主流 ◦ そもそも認可の範囲を超えてるかも → OpenID Connect ◉ それぞれに適切なセキュリティ対策も提示されているので 合わせて適用しよう(→ 『OAuth 徹底入門』) ユースケースに合わせたパターンを選ぶ 33
  34. Any questions ? You can find me at @tmd45 Presentation

    template by SlidesCarnival Thanks! 34
  35. 参考: 公式資料 35 ◉ RFC 6749 - The OAuth 2.0

    Authorization Framework ◉ RFC 6750 - The OAuth 2.0 Authorization Framework: Bearer Token Usage ◉ 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 日本語訳 公開資料