Slide 1

Slide 1 text

仕様が読めるようになる OAuth2.0、OpenID Connect入門 2023 年 10 月 5 日 Auth屋 1

Slide 2

Slide 2 text

Auth屋 is 誰 ? OAuth2.0、OpenID Connectの本を書いてます 商業誌 同人誌 Boothで販売中 https://authya.booth.pm/ Amazon、その他書店で発売中 2

Slide 3

Slide 3 text

監修者 いとう りょうさん(@ritou) ● OpenID Connect Core1.0の コントリビュータ ● OpenIDファウンデーション・ジャパン のエバンジェリスト ● Identity Dance School #iddance 3

Slide 4

Slide 4 text

アンケート 4

Slide 5

Slide 5 text

RFC6749 (OAuth2.0の基本仕様) OAuthでは, クライアントは, リソースオーナーのコントロー ル下にありリソースサーバーによってホストされているリ ソースへのアクセス権を要求する. そしてリソースオーナー のクレデンシャルそのものとは別のクレデンシャルを取得す る. 5 引用元: OpenID ファウンデーション・ジャパン による日本語訳 http://openid-foundation-japan.github.io/rfc6749.ja.html

Slide 6

Slide 6 text

RFC6749 (OAuth2.0の基本仕様) OAuthでは, クライアントは, リソースオーナーのコントロー ル下にありリソースサーバーによってホストされているリ ソースへのアクセス権を要求する. そしてリソースオーナー のクレデンシャルそのものとは別のクレデンシャルを取得す る. 6 引用元: OpenID ファウンデーション・ジャパン による日本語訳 http://openid-foundation-japan.github.io/rfc6749.ja.html 最後に見返します

Slide 7

Slide 7 text

基本的な用語と概念を理解すれば読める 7

Slide 8

Slide 8 text

目次 OAuth ● 登場人物 ● OAuthとは何か ● OAuthのメリット ● OAuthのフロー ● OAuthでログイン? OpenID Connect ● OpenID Connectとは ● IDトークンとは 8

Slide 9

Slide 9 text

OAuthの登場人物 9

Slide 10

Slide 10 text

OAuthの登場人物 10 ユーザー 画像編集アプリ Google OAuth Google Photo API

Slide 11

Slide 11 text

OAuthの登場人物 11 ユーザー 画像編集アプリ Google OAuth Google Photo API Google Photo から 画像をダウンロード

Slide 12

Slide 12 text

OAuthの登場人物 12 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー)

Slide 13

Slide 13 text

OAuthの登場人物 13 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) 写真・動画などの リソースを保持

Slide 14

Slide 14 text

OAuthの登場人物 14 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) アクセストークンを発 行

Slide 15

Slide 15 text

OAuthの登場人物 15 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) アプリのユーザー Google Photo のユーザー (リソースの所有者)

Slide 16

Slide 16 text

OAuthの登場人物 16 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) リソース を利用するアプリ

Slide 17

Slide 17 text

OAuthの登場人物 | 2つのクライアント 17 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) クライアントシークレットを安 全に保持できない パブリッククライアント

Slide 18

Slide 18 text

OAuthの登場人物 | 2つのクライアント 18 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) クライアントシークレットを 安全に保持できる コンフィデンシャルクライアント

Slide 19

Slide 19 text

OAuthとは何か 19

Slide 20

Slide 20 text

OAuthとは何か ● RFC6749「OAuth2.0 はサードパーティアプリケーションによる HTTP サービスへの限定的なアクセスを可能にする認可フレームワークである」 ● 例「OAuth2.0は画像編集アプリによるGoogle Photo への限定的なアクセ ス(Aさんの画像のダウンロード)を可能にするアクセストークンの発行 ルールである」 20 RFC6749の用語 画像編集アプリの例 サードパーティアプリ 画像編集アプリ HTTPサービス Google Photo 限定的なアクセス Aさんの画像のダウンロードのみ 認可フレームワーク アクセストークンの発行ルール

Slide 21

Slide 21 text

OAuth の流れ 21 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) Google Photoから写真を ダウンロード

Slide 22

Slide 22 text

OAuth の流れ 22 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) Google Photo APIに アクセスしたい

Slide 23

Slide 23 text

OAuth の流れ 23 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) Google Photoのリソース オーナーとしての認証

Slide 24

Slide 24 text

OAuth の流れ 24 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) 画像編集アプリにGoogle Photoの 画像のダウンロードを許可します か?

Slide 25

Slide 25 text

OAuth の流れ 25 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) 許可します

Slide 26

Slide 26 text

OAuth の流れ 26 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) アクセストークン発行

Slide 27

Slide 27 text

OAuth の流れ 27 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) 画像ダウンロードします

Slide 28

Slide 28 text

OAuth の流れ 28 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) アクセストークンのチェック

Slide 29

Slide 29 text

OAuth の流れ 29 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) 画像どうぞ

Slide 30

Slide 30 text

OAuthを使うメリット 30

Slide 31

Slide 31 text

OAuthは何が嬉しいのか ● 画像編集アプリにGoogleの認証情報(ID、パスワードなど)を渡す必要がない 31 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) 認証

Slide 32

Slide 32 text

OAuthがない場合 32 32 Aさん 画像編集アプリ Google Photo API

Slide 33

Slide 33 text

OAuthがない場合 33 33 Aさん 画像編集アプリ Google Photo API Googleの ID/パスワード

Slide 34

Slide 34 text

OAuthがない場合 | ケース1 34 34 Aさん 悪意ある 画像編集アプリ Google Photo API Googleの ID/パスワード

Slide 35

Slide 35 text

OAuthがない場合 | ケース2 35 35 Aさん 画像編集アプリ Google Photo API Googleの ID/パスワード

Slide 36

Slide 36 text

OAuthがない場合 | ケース2 36 36 ユーザー 画像編集アプリ Google Photo API Googleの ID/パスワード

Slide 37

Slide 37 text

OAuthがない場合 | ケース2 37 37 ユーザー 画像編集アプリ Google Photo API Aさんの Google Photoで なんでもできる

Slide 38

Slide 38 text

OAuthがある場合 38 38 ユーザー 画像編集アプリ Google OAuth Google Photo API アクセストークン

Slide 39

Slide 39 text

OAuthがある場合 39 39 ユーザー 画像編集アプリ Google OAuth Google Photo API Aさんの画像の ダウンロードだけを 一定期間できる

Slide 40

Slide 40 text

OAuthのフロー 40

Slide 41

Slide 41 text

OAuthのフロー(グラント) ● 認可コードフロー ● インプリシットフロー ● リソースオーナーパスワードクレデンシャルフロー ● クライアントクレデンシャルフロー 41

Slide 42

Slide 42 text

OAuthのフロー(グラント) ● 認可コードフロー ● インプリシットフロー ← 非推奨 ● リソースオーナーパスワードクレデンシャルフロー ← 特殊ケース ● クライアントクレデンシャルフロー ← ユーザー関係しない 42

Slide 43

Slide 43 text

クライアントの登録 43 ユーザー (リソースオーナー)ç 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) APIを利用するアプリと して事前に登録

Slide 44

Slide 44 text

クライアントの登録 44 ● 一般的には開発者向けサイトでアプリの情報を登録 ● クライアントID・クライアントシークレットの発行を受ける

Slide 45

Slide 45 text

クライアントの登録 45

Slide 46

Slide 46 text

クライアントの登録 46 { "web": { "client_id": "7429476-bb2mshkghp5bje196p9pvugi1av19.apps.googleusercontent.com", "project_id": "storied-box-250407", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_secret": "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uww", "redirect_uris": [ "https://offers.example.com/callback" ] } }

Slide 47

Slide 47 text

クライアントの登録 47 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) クライアントID クライアントシークレット

Slide 48

Slide 48 text

クライアントの登録 48 ユーザー (リソースオーナー) 画像編集アプリ (クライアント) Google OAuth (認可サーバー) Google Photo API (リソースサーバー) アプリの リダイレクトURI

Slide 49

Slide 49 text

認可コードフロー 49

Slide 50

Slide 50 text

認可コードフロー 50 Step1 ROの認証 権限委譲の同意 ↓ 認可コードの発行

Slide 51

Slide 51 text

認可コードフロー 51 Step2 クライアント認証 ↓ アクセストークンの発行

Slide 52

Slide 52 text

認可コードフロー 52 Step1 ROの認証 権限委譲の同意 ↓ 認可コードの発行

Slide 53

Slide 53 text

認可コードフロー 53 Google Photoから ダウンロード

Slide 54

Slide 54 text

認可コードフロー 54 Google Photoの画像の ダウンロード権限の リクエスト

Slide 55

Slide 55 text

認可コードフロー 55 認可リクエスト

Slide 56

Slide 56 text

認可コードフロー 56 認可エンドポイント

Slide 57

Slide 57 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 57

Slide 58

Slide 58 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 58 レスポンスタイプ= 認可コード

Slide 59

Slide 59 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 59 クライアントID

Slide 60

Slide 60 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 60 セッションと紐づけたランダムな文字列 クロスサイトリクエストフォージェリー対策

Slide 61

Slide 61 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 61 Redirect URI

Slide 62

Slide 62 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 62 スコープ

Slide 63

Slide 63 text

スコープ ● アクセストークンに紐付ける権限 ● 権限の内容、表現方法は仕様では規定されていない(サービスごとに違う) ● Googleの例 https://www.googleapis.com/auth/photoslibrary.readonly Google Photoのリソースに対する読み込み権限 https://www.googleapis.com/auth/photoslibrary.appendonly Google Photoのリソースに対する書き込み権限 https://www.googleapis.com/auth/photoslibrary.sharing Google Photoのリソースに対するアルバムの作成、共有などの権限 63

Slide 64

Slide 64 text

認可リクエスト GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=htts://offers.example.com/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 64

Slide 65

Slide 65 text

認可コードフロー 65 リソースオーナーの認証 権限委譲の同意

Slide 66

Slide 66 text

認証画面と同意画面 66

Slide 67

Slide 67 text

認可コードフロー 67 リソースオーナーの認証 権限委譲の同意

Slide 68

Slide 68 text

認可コードフロー 68 認可コード 発行します

Slide 69

Slide 69 text

認可コードフロー 69 リダイレクトURLに 認可コードを渡す リダイレクトURI

Slide 70

Slide 70 text

認可コードフロー 70 認可レスポンス

Slide 71

Slide 71 text

認可レスポンス 302 Found Location: https://offers.example.com/callback ?state=s6Bh…Rkqt3 &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &scope=https://www.googleapis.com/auth/photoslibrary.readonly 71

Slide 72

Slide 72 text

認可レスポンス 302 Found Location: https://offers.example.com/callback ?state=s6Bh…Rkqt3 &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &scope=https://www.googleapis.com/auth/photoslibrary.readonly 72 リダイレクトURI

Slide 73

Slide 73 text

認可レスポンス 302 Found Location: https://offers.example.com/callback ?state=s6Bh…Rkqt3 &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &scope=https://www.googleapis.com/auth/photoslibrary.readonly 73 認可リクエストで送ったstate

Slide 74

Slide 74 text

認可レスポンス 302 Found Location: https://offers.example.com/callback ?state=s6Bh…Rkqt3 &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &scope=https://www.googleapis.com/auth/photoslibrary.readonly 74 認可コード

Slide 75

Slide 75 text

認可レスポンス 302 Found Location: https://offers.example.com/callback ?state=s6Bh…Rkqt3 &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &scope=https://www.googleapis.com/auth/photoslibrary.readonly 75 スコープ

Slide 76

Slide 76 text

認可コードフロー 76 認可コードが クライアントに渡る

Slide 77

Slide 77 text

認可コードフロー 77 Step1 ROの認証 権限委譲の同意 ↓ 認可コードの発行

Slide 78

Slide 78 text

認可コードフロー 78 Step2 クライアント認証 ↓ アクセストークンの発行

Slide 79

Slide 79 text

認可コードフロー 79 アクセストークンの 発行リクエスト

Slide 80

Slide 80 text

認可コードフロー 80 トークンリクエスト

Slide 81

Slide 81 text

認可コードフロー 81 トークンエンドポイント

Slide 82

Slide 82 text

トークンリクエスト POST /token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=https://offers.example.com/callback 82

Slide 83

Slide 83 text

トークンリクエスト POST /token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=https://offers.example.com/callback 83 クライアントID

Slide 84

Slide 84 text

トークンリクエスト POST /token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=https://offers.example.com/callback 84 クライアントシークレット

Slide 85

Slide 85 text

トークンリクエスト POST /token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=https://offers.example.com/callback 85 認可コードグラント(フロー)

Slide 86

Slide 86 text

トークンリクエスト POST /token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=https://offers.example.com/callback 86 認可コード

Slide 87

Slide 87 text

トークンリクエスト POST /token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=https://offers.example.com/callback 87 リダイレクトURI

Slide 88

Slide 88 text

認可コードフロー 88 トークンリクエスト

Slide 89

Slide 89 text

認可コードフロー 89 アクセストークンの 発行

Slide 90

Slide 90 text

認可コードフロー 90 トークンレスポンス

Slide 91

Slide 91 text

トークンレスポンス { "access_token": "ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/photoslibrary.readonly", "token_type": "Bearer" } 91

Slide 92

Slide 92 text

トークンレスポンス { "access_token": "ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/photoslibrary.readonly", "token_type": "Bearer" } 92 アクセストークン

Slide 93

Slide 93 text

トークンレスポンス { "access_token": "ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/photoslibrary.readonly", "token_type": "Bearer" } 93 有効期限[秒]

Slide 94

Slide 94 text

トークンレスポンス { "access_token": "ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/photoslibrary.readonly", "token_type": "Bearer" } 94 スコープ

Slide 95

Slide 95 text

トークンレスポンス { "access_token": "ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv", "expires_in": 3600, "scope": "https://www.googleapis.com/auth/photoslibrary.readonly", "token_type": "Bearer" } 95 ベアラートークンであ ることを示す

Slide 96

Slide 96 text

認可コードフロー 96 アクセストークン ゲット

Slide 97

Slide 97 text

認可コードフロー 97 Step1 ROの認証 権限委譲の同意 認可コードの発行 Step2 クライアント認証 アクセストークンの発行

Slide 98

Slide 98 text

リソースサーバーへのアクセス 98

Slide 99

Slide 99 text

リソースサーバーへのアクセス 99 ヘッダーにアクセストーク ンをセットして APIにアクセス

Slide 100

Slide 100 text

リソースサーバーへのアクセス GET /v1/albums Host: photoslibrary.googleapis.com Authorization: Bearer ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv 100

Slide 101

Slide 101 text

リソースサーバーへのアクセス GET /v1/albums Host: photoslibrary.googleapis.com Authorization: Bearer ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv 101 Authorizationヘッダー

Slide 102

Slide 102 text

リソースサーバーへのアクセス GET /v1/albums Host: photoslibrary.googleapis.com Authorization: Bearer ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv 102 文字列「Bearer」

Slide 103

Slide 103 text

リソースサーバーへのアクセス GET /v1/albums Host: photoslibrary.googleapis.com Authorization: Bearer ya29.GlscB0j4x.....DsR9iOiU-BfZjTXWUJ7olv 103 アクセストークン

Slide 104

Slide 104 text

リソースサーバーへのアクセス 104 画像のダウンロード

Slide 105

Slide 105 text

OAuthでログイン? 105

Slide 106

Slide 106 text

ところで OAuthって「ソーシャルログイン」でつかわれてるんじゃないの? 106

Slide 107

Slide 107 text

OAuth 認可コードフロー ふりかえり 107

Slide 108

Slide 108 text

認可コードフロー 108 ここでGoogle アカウントで認 証してるよね?

Slide 109

Slide 109 text

OAuth 認可コードフロー ふりかえり 109 アクセスするリソース(画像)のオー ナーは誰かを確認

Slide 110

Slide 110 text

OAuth 認可コードフロー ふりかえり 110 アクセスするリソース(画像)のオー ナーは誰かを確認 アプリにログインさせるための 認証をおこなっているわけではない

Slide 111

Slide 111 text

OAuth 認可コードフロー ふりかえり 111 そもそもここで アプリにはログイン状態

Slide 112

Slide 112 text

OAuthとアプリへのログインの関係 ● OAuthと「アプリへのログイン」は関係ない ● が、SNSのリソース(SNSユーザーのプロフィール情報)を利用して、次の ようなことが行われていた時代がある(今もある?) 112

Slide 113

Slide 113 text

SNSの例 | 登場人物 113 ほげアプリ (クライアント) 認可サーバー プロフィール API (リソースサーバー) Aさん (リソースオーナー)

Slide 114

Slide 114 text

SNSの例 | 登場人物 114 ほげアプリ (クライアント) 認可サーバー プロフィール API (リソースサーバー) SNSのユーザー ほげアプリのユーザー Aさん (リソースオーナー) 「SNS アカウントでログ イン」機能 SNS ユーザーの プロフィール情報を 提供するAPI

Slide 115

Slide 115 text

SNSの例 115

Slide 116

Slide 116 text

SNSの例 116 SNS アカウントで ログイン

Slide 117

Slide 117 text

SNSの例 117 OAuth

Slide 118

Slide 118 text

SNSの例 118 OAuth Aさんのプロフィール情報にア クセスするための アクセストークン

Slide 119

Slide 119 text

SNSの例 119 OAuth プロフィール情報の リクエスト

Slide 120

Slide 120 text

SNSの例 120 OAuth Aさんの プロフィール情報の

Slide 121

Slide 121 text

SNSの例 121 OAuth Aさんのプロフィール情報 からユーザー識別子を確認してロ グイン完了

Slide 122

Slide 122 text

この実装には脆弱性がある ● アクセストークンを差し替えられると、ほげアプリも SNSサービスもそれに気づけない ● アクセストークンには差し替えに気づく仕組みがない 122

Slide 123

Slide 123 text

SNSの例 123 OAuth Bさんのアクセストークン に差し替えられた Bさんとしてログイン Aさん

Slide 124

Slide 124 text

この実装には脆弱性がある ● アクセストークンを差し替えられると、ほげアプリも SNSサービスもそれに気づけない ● アクセストークンには差し替えに気づく仕組みがない 124 OpenID Connectを使いましょう

Slide 125

Slide 125 text

OpenID Connectとは 125

Slide 126

Slide 126 text

登場人物 ● OAuthとOpenID Connectでは登場人物の呼び名が異なります 126 OAuth リソースオーナー OIDC エンドユーザー OAuth クライアント OIDC リライング・パーティ OAuth 認可サーバー OIDC IDプロバイダ OAuth リソースサーバー OIDC (User Info API)

Slide 127

Slide 127 text

OpenID Connectとは 何をやっている? ● ユーザー認証を外部サービス(IDプロバイダ)におまかせし、アプリはID トークンを受け取って、IDプロバイダによる認証内容を確認する 何に使う? ● ソーシャルログイン 仕組みは? ● OAuthを拡張したプロトコル 127 OpenID Connect = OAuth + ID トークン + UserInfo API

Slide 128

Slide 128 text

OpenID Connectとは 何をやっている? ● ユーザー認証を外部サービス(IDプロバイダ)におまかせし、アプリはID トークンを受け取って、IDプロバイダによる認証内容を確認する 何に使う? ● ソーシャルログイン 仕組みは? ● OAuthを拡張したプロトコル 128 OpenID Connect = OAuth + ID トークン + UserInfo API プロフィールAPIの 形式を規定

Slide 129

Slide 129 text

OpenID Connectとは 何をやっている? ● ユーザー認証を外部サービス(IDプロバイダ)におまかせし、アプリはID トークンを受け取って、IDプロバイダによる認証内容を確認する 何に使う? ● ソーシャルログイン 仕組みは? ● OAuthを拡張したプロトコル 129 OpenID Connect = OAuth + ID トークン + UserInfo API IDトークンを理解 = OIDCを理解

Slide 130

Slide 130 text

IDトークンとは 誰が発行する? ● IDプロバイダ 誰が何のために使うのか? ● リライング・パーティがエンドユーザーを認証するため どんな情報が含まれているか ● ユーザーID ● トークンの有効性(有効期限、発行日時) ● トークン発行者ID、トークン受領者ID ● 改ざんを防ぐための署名 ● トークンのフォーマットに関する情報 130

Slide 131

Slide 131 text

IDトークンとは 形式は? ● Json Web Token(JWT) ● .(ドット)で区切られる3つのパートからなる ● ヘッダーとペイロードはBase64エンコードされたJSON eyJhbGci…QifQ. eyJpc3M…I6MTU2MzH0.Bx9Eds2f…CeekBuYokY Bx9Edsrn2f3・・・・・・CeekBuYokYnxt4A3XRSSfcpvg 131 ヘッダー ペイロード 署名

Slide 132

Slide 132 text

IDトークン | ヘッダー { "typ": "JWT", "alg": "RS256", } 132

Slide 133

Slide 133 text

IDトークン | ヘッダー { "typ": "JWT", "alg": "RS256", } 133 署名アルゴリズム

Slide 134

Slide 134 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, } 134

Slide 135

Slide 135 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, } 135 Issuer: 発行者

Slide 136

Slide 136 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, } 136 Audience: IDトークンを受け取るリライング・パー ティのクライアントID

Slide 137

Slide 137 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, } 137 Subject: エンドユーザーの識別子

Slide 138

Slide 138 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, } 138 Issue at : JWTの発行時間(UNIX time)

Slide 139

Slide 139 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, } 139 Expiration time : 有効期限(UNIX time)

Slide 140

Slide 140 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", "aud": "6727653....ibqog5.apps.googleusercontent.com", "sub": "103567684956724214211", "iat": 1563792930, "exp": 1563796530, "email": "[email protected]" "name": "Auth屋", "given_name": "屋", "family_name": "Auth" } 140 scope(email profile)を 追加すると、対応して情報が増える

Slide 141

Slide 141 text

IDトークン | 署名 なぜ署名が必要? ● sub(ユーザー識別子)、iss(発行者)、aud(発行先)などが改ざんされ ていないことを保証 署名アルゴリズムは? ● ヘッダーに記載(RS256) 署名検証用の公開鍵は? ● IDプロバイダが公開 ● https://www.googleapis.com/oauth2/v3/certs Bx9Edsrn2f3・・・・・・CeekBuYokYnxt4A3XRSSfcpvg 141

Slide 142

Slide 142 text

OIDC 認可コードフロー 142

Slide 143

Slide 143 text

OIDC 認可コードフロー 143 SNSアカウントで ログイン

Slide 144

Slide 144 text

OIDC 認可コードフロー 144 認証リクエスト

Slide 145

Slide 145 text

OIDC 認可コードフロー 145 scope = openid

Slide 146

Slide 146 text

OIDC 認可コードフロー 146 scope = openid email profile

Slide 147

Slide 147 text

OIDC 認可コードフロー 147 アクセストークン IDトークン

Slide 148

Slide 148 text

OIDC 認可コードフロー 148 IDトークンのsub を確認して ログイン完了

Slide 149

Slide 149 text

ログイン時以外のタイミングで取得する場合 149 プロフィール情報の リクエスト UserInfo API

Slide 150

Slide 150 text

ログイン時以外のタイミングで取得する場合 150 プロフィール情報 UserInfo API

Slide 151

Slide 151 text

OIDC 認可コードフロー 151 IDトークンのsub を確認して ログイン完了

Slide 152

Slide 152 text

IDトークン | ペイロード { "iss": "https://accounts.google.com", ← 発行者 "aud": "6727653....ibqog5.apps.googleusercontent.com", ← 受領者 "sub": "103567684956724214211", ← ユーザーID "iat": 1563792930, ← 発行日時 "exp": 1563796530, ← 有効期限 } 入れ替えられても、気付ける仕組みがある 署名により改ざんも気付ける 152

Slide 153

Slide 153 text

説明していないこと ● パブリッククライアントのフロー ● PKCE ● リフレッシュトークン ● 攻撃と対策(state、nonce、etc.) ● 他のフロー ● etc. 153

Slide 154

Slide 154 text

宣伝 | 同人誌 Boothで販売中 https://authya.booth.pm / 雰囲気OAuth本 OIDC本 攻撃本 154

Slide 155

Slide 155 text

RFC6749 (OAuth2.0の基本仕様) OAuthでは, クライアントは, リソースオーナーのコント ロール下にありリソースサーバーによってホストされている リソースへのアクセス権を要求する. そしてリソースオー ナーのクレデンシャルそのものとは別のクレデンシャルを取 得する. 155 引用元: OpenID ファウンデーション・ジャパン による日本語訳 http://openid-foundation-japan.github.io/rfc6749.ja.html

Slide 156

Slide 156 text

RFC6749 (OAuth2.0の基本仕様) 保護されたリソースにアクセスする為にリソースオーナーの クレデンシャルを使う代わりに, クライアントはアクセス トークンを取得する. アクセストークンとは, ある特定のス コープ, 期間およびその他のアクセス権に関する情報を示す 文字列である. アクセストークンはリソースオーナーの同意 をもって認可サーバーからサードパーティークライアントへ 発行される. クライアントはアクセストークンを用いてリ ソースサーバーがホストしている保護されたリソースにアク セスする. 156

Slide 157

Slide 157 text

デモ 157

Slide 158

Slide 158 text

Google の トークンを取得 ● Google からアクセストークンとIDトークンを取得します ● 雰囲気OAuth本に乗せている方法 ○ 認可・認証リクエストをブラウザで実施 ○ トークンリクエストをcurlコマンドで実施 158

Slide 159

Slide 159 text

認可コードフロー(OIDC) 159 認証リクエスト(OIDC)

Slide 160

Slide 160 text

認可コードフロー 160 認可エンドポイント https://accounts.google.com/o/oauth2/v2/auth

Slide 161

Slide 161 text

認証リクエスト GET /o/oauth2/v2/auth ?client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &response_type=code &scope=openid &redirect_uri=http://localhost/callback &state=xyz 161

Slide 162

Slide 162 text

認可コードフロー 162 リソースオーナーの認証 権限委譲の同意

Slide 163

Slide 163 text

認可コードフロー 163 リダイレクトURLに 認可コードを渡す http://localhost/callback

Slide 164

Slide 164 text

認可コードフロー 164 トークンリクエスト

Slide 165

Slide 165 text

認可コードフロー 165 トークンエンドポイント https://www.googleapis.com/oauth2/v4/token

Slide 166

Slide 166 text

トークンリクエスト POST /oauth2/v4/token Host: www.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &client_secret=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uww &grant_type=authorization_code &code=4%2FZQHK-DEk0Jfp4drQ-3iZ4fwFYf48vyaOf..... &redirect_uri=http://localhost/callback 166

Slide 167

Slide 167 text

認可リクエスト(Google Photo) GET /authorize ?response_type=code &client_id=7429476…bje196p9pvugi1av19.apps.googleusercontent.com &state=s6Bh…Rkqt3 &redirect_uri=http://localhost/callback &scope=https://www.googleapis.com/auth/photoslibrary.readonly 167