Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

◉ OpenID TechNight で OpenID Connect とはなんぞやとい うのを聞いてきた ○ 2015/09/09 社外勉強会参加 ブログ ◉ 各プロバイダの認証プロトコル #補足 ○ 2016/04/27 社内記事(↑で聞いた話) 過去の OAuth 系共有実績Ⅰ 3

Slide 4

Slide 4 text

過去の OAuth 系共有実績Ⅱ 4 ◉ OpenID BizDay で金融 API の動向について聞いてきた ○ 2017/08/02 社外勉強会参加 ブログ ◉ FAPI Security について聞いてきた話 ○ 2017/08/18 社内勉強会 スライド(↑で聞いた話)

Slide 5

Slide 5 text

今日のおはなしの主な元ネタ 5 ◉ OAuth 2.0の代表的な利用パターンを仕様から理解しよう ○ 2017/07/21 Build INSIDER 連載記事より ○ 著者は Nov 氏。ぶっちゃけほぼこの記事の話+α ◉ 書籍 『OAuth 徹底入門』 ○ 2019/01/30 発行, 原著 『OAuth 2 in Action』 2017/03/18

Slide 6

Slide 6 text

イントロダクション OAuth 2.0 の基本をおさらい 6

Slide 7

Slide 7 text

登場人物 7 認可サーバー 例: account.google.com リソースサーバー 例: Calendar API リソースオーナー 例: エンドユーザー OAuth クライアント 例: iOS Calendar App クライアントアクセス を認可する アクセストークン API アクセス エンドユーザーの認証 トークンの発行・管理 トークンを受け入れて 実際の API を提供 図引用元: https://www.buildinsider.net/enterprise/openid/oauth20

Slide 8

Slide 8 text

◉ 認可(Authorization, AuthZ) ○ OAuth クライアントが必要とするリソースへの アクセスをリソースオーナーに許可してもらう ◉ 認証(Authentication, AuthN) ○ 取得したリソースをもとにしてOAuth クライアントが リソースオーナーを「 A さんだ」と確証する 認可と認証 8

Slide 9

Slide 9 text

◉ 実体(Entity) ○ エンドユーザー、人間そのもの ○ システムは直接「実体」を認識できない ◉ 属性(Identity) ○ エンドユーザの ID, 個人情報など、リソース ○ システムは属性をもとにして「いまブラウザの前にいる のは A さんである」という確証を得る 実体と属性 9

Slide 10

Slide 10 text

◉ ID 連携の場合は認可サーバとは別にユーザを 管理する第5の登場人物が加わる ◉ そのため OAuth 2.0 を拡張した仕様(OpenID Connect)が必要となる ○ OpenID Connectは「OAuth 2.0 にどのような機能を 追加すればセキュアな ID 連携が可能となるのか」と いう視点で策定された仕様 ID 連携 10

Slide 11

Slide 11 text

登場人物 11 認可サーバー 例: account.google.com リソースサーバー 例: Calendar API OAuth クライアント 例: iOS Calendar App リソースオーナー 例: エンドユーザー クライアントアクセス を認可する アクセストークン API アクセス エンドユーザーの認証 トークンの発行・管理 トークンを受け入れて 実際の API を提供 OAuth クライアント バックエンド クライアント独自の ユーザ管理

Slide 12

Slide 12 text

◉ 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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

OAuth 2.0 ユースケース ユースケースによって何が違うのか 15

Slide 16

Slide 16 text

◉ OAuth クライアントの特性によって分かれる ○ サーバーサイドで動作する Web アプリ ○ JS アプリ(アプリ独自バックエンドなし) ○ JS アプリ(アプリ独自バックエンドあり) ○ ネイティブアプリ(アプリ独自バックエンドなし) ○ ネイティブアプリ(アプリ独自バックエンドあり) 主なユースケース 16

Slide 17

Slide 17 text

認可サーバー 例: account.google.com ユーザ認証とクライアント認証 17 リソースオーナー 例: エンドユーザー OAuth クライアント 例: iOS Calendar App ユーザー認証: User ID / Password クライアント認証: App ID / Secret ユーザー認証

Slide 18

Slide 18 text

◉ secret を秘匿に保てる(Confidential Client) ○ サーバーへの不正侵入などがない限り安全 ○ クライアント認証が行える ◉ (あとで実行されるバッチ処理など)比較的長期間 有効な API アクセス権限を必要とする ◉ クライアントが認証されているので、発行されるアクセストーク ンの有効期限を伸ばしたり、リフレッシュトークンを使えるよう にしたり、利用できる Permission を多くしたりしても安心 Web アプリ 18 もっとも基本となる OAuth 2.0 ユースケース

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

◉ secret を秘匿に保てない(Public Client) ○ クライアント認証が行えない ◉ 常にユーザーがブラウザーの前にいることが期待できるた め必要に応じて API アクセス権限を再取得可能 ◉ バックエンド側でユーザーのデータを管理しているため バックグラウンドではユーザー認証が必要 ◉ "ID 連携" に該当するため OAuth 2.0 ケースの範囲外※ JS アプリ(独自バックエンドあり) 20

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

OAuth 2.0 利用パターン ユースケースに適したフローを知る 23

Slide 24

Slide 24 text

◉ 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 ユースケース

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

◉ Implicit Flow を利用するケース ○ クライアントの身元を保証する手段は redirect_uri しかな い ○ redirect_uri が他のアプリに乗っ取られてしまうようなケー スでは Access Token が容易に第三者に漏えいする ■ 第三者のアプリに利用されてしまうリスクをはらんでい る iOS/Android の Custom Schema URL の利用には リスクを伴う ネイティブアプリ(独自バックエンドなし) 26

Slide 27

Slide 27 text

◉ Authorization Code Flow を利用するケース ○ 一度ログインしてしまえばそれ以降はずっとログイン状態と いう UX を保つために、継続的に API アクセスが必要なアプ リの場合、長期間有効なアクセストークンが必要 ○ Access Token の有効期限は短いが、Refresh Token の仕 組みで適宜新しいアクセストークンを再発行できる ○ ただしこの場合でも "クライアント認証を行えない" という特 徴は変わらない (RFC 6749 - Section 4.1.3) ネイティブアプリ(独自バックエンドなし) 27

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

◉ Hybrid Flow で取得した Authorization Code をバックエン ドに送るパターン ○ Hybrid Flow は RFC 6749 では定義されていない、OpenID Connect の策定段階に出てきた OAuth 2.0 の拡張仕様 ○ アプリで使うための Access Token と、バックエンドに送るた めの Authorization Code を同時に得る ○ バックエンドから認可サーバーへアクセストークンを要求す るときにクライアント認証を行うことができるため Token 置換 攻撃を意識する必要がない JS アプリ / ネイティブアプリ(独自バックエンドあり) 29

Slide 30

Slide 30 text

◉ OAuth 2.0 の最初の仕様(RFC6749)に含まれていないた め、すべての API プラットフォームで利用できるわけではな い ○ 認可サーバー側がそのフローに対応するかどうか決 める ○ Facebook や Google は対応している ○ response_type=code%20token is Hybrid Hybrid Flow すごーい 30

Slide 31

Slide 31 text

◉ 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

Slide 32

Slide 32 text

まとめ 結局いろいろあって難しくね? 32

Slide 33

Slide 33 text

◉ ユースケースとパターンは提示されている ◉ 適切なパターンを選んで実装しよう ○ なんでもかんでも Implicit Flow とかダメよ ○ ネイティブアプリとの連携も今や主流 ○ そもそも認可の範囲を超えてるかも → OpenID Connect ◉ それぞれに適切なセキュリティ対策も提示されているので 合わせて適用しよう(→ 『OAuth 徹底入門』) ユースケースに合わせたパターンを選ぶ 33

Slide 34

Slide 34 text

Any questions ? You can find me at @tmd45 Presentation template by SlidesCarnival Thanks! 34

Slide 35

Slide 35 text

参考: 公式資料 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 日本語訳 公開資料