Slide 1

Slide 1 text

やさしく入門するOAuth2.0

Slide 2

Slide 2 text

自己紹介 - 名前: 阿部 真之 - 仕事: 株式会社ゆめみ でAndroidエンジニアしてます - 最近はサーバサイド Kotlinの仕事も始めました - ほぼサーバーサイドどっぷりです - 趣味 - コーヒー、ビール、アニメ、ゲーム、読書、 etc… - Twitter: @marchin_1989

Slide 3

Slide 3 text

アジェンダ - 認証と認可の違い - OAuth2.0とは - OAuth2.0の4つの認可グラント - パブリッククライアントでの認可コードグラント - 開発視点でのOAuth - まとめ

Slide 4

Slide 4 text

前置き - この講座の対象者は、「OAuth2.0という言葉を聞いたことはある」ぐらいの開発者 が対象です - この講座のゴールとしては、ざっくり「OAuthとは?」のイメージを持って帰ってもらう ことです。 - 細かい説明をしすぎると全体像が掴めなくなってしまうため、リクエスト時などのパ ラメータやトークンの渡し方など、説明を端折ってる箇所があります。参考にした文 献は、スライドの最後に載せてますので、詳しくはそちらでチェックしてください。 - セキュリティに関することなので、慎重にご判断ください。 - ご指摘事項は真摯に受け止めます。間違いを発見した場合や、ご意見がある場合 はご指摘いただけますと幸いです。

Slide 5

Slide 5 text

認証と認可の違いは?

Slide 6

Slide 6 text

認証と認可の違い - 認証(Authentication) - 誰であるかを確認すること。 - 例: Webサービスのログイン。行政サービス、携帯の契約、本人限定郵便 etcでの本人確認。 - 認可(Authorization) - 権限の割り当てを行うこと。 - 例: 電車の切符。ディズニーランドの入園チケット。

Slide 7

Slide 7 text

認証と認可の違い - 認証(Authentication) - 誰であるかを確認すること。 - 例: Webサービスのログイン。行政サービス、携帯の契約、本人限定郵便 etcでの本人確認。 - 認可(Authorization) - 権限の割り当てを行うこと。 - 例: 電車の切符。ディズニーランドの入園チケット。 認可を取得するために、認証をすることがあ るので、混同しやすいが、認証と認可は別 物。

Slide 8

Slide 8 text

認証と認可の違い - 認証(Authentication) - 誰であるかを確認すること。 - 例: Webサービスのログイン。行政サービス、携帯の契約、本人限定郵便 etcでの本人確認。 - 認可(Authorization) - 権限の割り当てを行うこと。 - 例: 電車の切符。ディズニーランドの入園チケット。 OAuth2.0は「認可」についての話です。 ※OAuth2.0は認可の仕組みだが、 OAuth2.0を拡張した認証 用の仕組みとして、OpenIDConnectというものがある。

Slide 9

Slide 9 text

OAuth2.0とは

Slide 10

Slide 10 text

OAuth2.0のよくあるつまずきポイント - 連携しようとしているサービス公式ガイドのOAuth2.0の説明に、複数のやり方が記 載されていて、結局自分の作ろうとしているアプリには、どれを使えばいいんだっ け?いっぱいあってどれかわからん。。 - 利用したいサービスに、「OAuth2.0に準拠」って書いてて、よくわからんがライブラ リ使ったらなんかできた。

Slide 11

Slide 11 text

OAuth2.0はなぜ必要? Question. あなたは、OAuth2.0なんて知らなかったとします。あなたの自作のアプリから、あるユー ザーのGoogleカレンダーに対して、データの操作をさせるとすると、どうやる?

Slide 12

Slide 12 text

Answer. ユーザーが、あなたの自作アプリに、Googleアカウントのクレデンシャル(ユーザーID、 パスワードなど)を渡して、代わりにアクセスしてもらう。。。? OAuth2.0はなぜ必要? ※クレデンシャル: ユーザ等の認証に用いられる情報の総称

Slide 13

Slide 13 text

Answer. ユーザーが、あなたの自作アプリに、Googleアカウントのクレデンシャル(ユーザーID、 パスワードなど)を渡して、代わりにアクセスしてもらう。。。? OAuth2.0はなぜ必要? ※クレデンシャル: ユーザ等の認証に用いられる情報の総称 サードパーティアプリ(あなたの自作アプリ)に対して、 ユーザーのGoogleアカウントのクレデンシャルを渡して しまっている。

Slide 14

Slide 14 text

Answer. ユーザーが、あなたの自作アプリに、Googleアカウントのクレデンシャル(ユーザーID、 パスワードなど)を渡して、代わりにアクセスしてもらう。。。? OAuth2.0はなぜ必要? ※クレデンシャル: ユーザ等の認証に用いられる情報の総称 ユーザーがGoogleのサービスで実行できることを、サー ドパーティアプリが無制限かつ無期限に 実行できてしま う。 カレンダーアプリでできることはもちろん、他のサービス も利用できる。。

Slide 15

Slide 15 text

Answer. ユーザーが、あなたの自作アプリに、Googleアカウントのクレデンシャル(ユーザーID、 パスワードなど)を渡して、代わりにアクセスしてもらう。。。? OAuth2.0はなぜ必要? ※クレデンシャル: ユーザ等の認証に用いられる情報の総称 じゃあ、クレデンシャルを渡さずに Googleカレンダー へのアクセス権限を渡すにはどうすればいい?

Slide 16

Slide 16 text

Answer. ユーザーが、あなたの自作アプリに、Googleアカウントのクレデンシャル(ユーザーID、 パスワードなど)を渡して、代わりにアクセスしてもらう。。。? OAuth2.0はなぜ必要? ※クレデンシャル: ユーザ等の認証に用いられる情報の総称 権限の範囲(スコープ) を絞って、さらに有効期限あり で、サービスにアクセスするためのチケット(トークン) を発行して、渡せばいいのでは?

Slide 17

Slide 17 text

Answer. ユーザーが、あなたの自作アプリに、Googleアカウントのクレデンシャル(ユーザーID、 パスワードなど)を渡して、代わりにアクセスしてもらう。。。? OAuth2.0はなぜ必要? ※クレデンシャル: ユーザ等の認証に用いられる情報の総称 権限の範囲(スコープ) を絞って、さらに有効期限あり で、サービスにアクセスするためのチケット(トークン) を発行して、渡せばいいのでは? →これがOAuth2.0のアイディア。 サービスを利用するためのチケット =アクセストークン

Slide 18

Slide 18 text

OAuth2.0とは - OAuth 2.0 は, サードパーティーアプリケーションによるHTTPサービスへの限定的 なアクセスを可能にする認可フレームワークである。(RFC6749) - サードパーティアプリに対して、アクセストークンを発行して、HTTPサービス(API) へのアクセスを認可する。 - 認可グラントという、アクセストークン(認可)の渡し方が、いくつか定義されている。

Slide 19

Slide 19 text

- サードパーティアプリに、ユーザーのクレデンシャル(ユーザーID、パスワード)を教 える必要がない。 - もし、悪意あるサードパーティアプリだったとしても、限定的なアクセス(閲覧のみな ど)しか許可していないため、被害の範囲を抑えられる。 - サードパーティアプリから、アクセストークンの漏洩はありうるが、ユーザのクレデン シャルを渡すよりも、影響は限定的。 - ユーザーが、サービスの管理画面で、サードパーティアプリへ発行したアクセストー クン(認可)を無効にできる。 OAuth2.0のメリット

Slide 20

Slide 20 text

Googleアカウントの、サードパーティアプリへのアクセス管理画面

Slide 21

Slide 21 text

OAuth2.0の登場人物(ロール)

Slide 22

Slide 22 text

OAuth2.0の登場人物(ロール) リソース所有者。 リソースへのアクセスを許可する 人。 ※人間でない場合もある。

Slide 23

Slide 23 text

OAuth2.0の登場人物(ロール) ・リソースオーナーの認可を得て、リソースオーナーの代理としてリソースにリクエ ストを行うアプリケーションをクライアントという。 ・クライアントの認証情報(クライアント ID、クライアントシークレット)を安全に保存 できるかどうかで、2つのクライアントタイプに分けられる。

Slide 24

Slide 24 text

OAuth2.0の登場人物(ロール) 「アクセストークン」をクライアントに発行す るサーバ。

Slide 25

Slide 25 text

OAuth2.0の登場人物(ロール) API。アクセストークンを検証することで、 リソースを提供する。

Slide 26

Slide 26 text

OAuth2.0の登場人物(ロール) クライアントの認証情報とは? 認可サーバーとのやり取りの際に、 OAuthクライアント自体の識別や、認証に利用され る情報。(クライアント ID、クライアントシークレット) ※リソースオーナー(エンドユーザー)の認証情報ではないので注意。 クライアント ID クライアントシークレット

Slide 27

Slide 27 text

OAuth2.0の登場人物(ロール) パブリッククライアント。 クライアントの認証情報(クライアント ID、クライアント シークレット)を安全に保存できない。 ブラウザベースのWebアプリ(SPA)や、ネイティブア プリ。

Slide 28

Slide 28 text

OAuth2.0の登場人物(ロール) パブリッククライアント。 クライアントの認証情報(クライアント ID、クライアント シークレット)を安全に保存できない。 ブラウザベースのWebアプリ(SPA)や、ネイティブア プリ。 コンフィデンシャルクライアント。 クライアントの認証情報を安全に保存できる。 サーバサイドアプリ。 ※OAuthとしては、サーバーサイドアプリも「クライアント」 という。

Slide 29

Slide 29 text

「クライアントの認証情報」についてもう少し補足 - リソースサーバーを提供するサービス上(開発者向けサイト)でクライアントの事前 登録が必要。 - クライアントの開発者は、自分のクライアント情報(リダイレクトURIなど)を事前に登 録し、「クライアントID」、「クライアントシークレット」を発行してもらう。 - クライアントタイプによっては、クライアントシークレットは利用しない(できない)。

Slide 30

Slide 30 text

クライアントの事前登録

Slide 31

Slide 31 text

認可グラント

Slide 32

Slide 32 text

OAuth2.0の認可グラント 認可を与える方法(仕様)がいくつか決められている。 1. 認可コードグラント 2. インプリシットグラント 3. リソースオーナーパスワードクレデンシャルグラント 4. クライアントクレデンシャルグラント

Slide 33

Slide 33 text

認可コードグラント - 「認可コード」という引換券を利用して、アクセストークンを取得する。 - パブリッククライアントでの利用は禁止されていないが、そのまま使うとセキュリティ 的に問題あり。OAuth2.0の拡張仕様などがある。 - 後述するPKCEを使って、パブリッククライアントで利用可能。最近(OAuth2.1)で は、認可コードグラントでPKCEを利用するのが必須。

Slide 34

Slide 34 text

実際に認可コードグラントでの認可を見てみる 講座内のみ動画を流します。

Slide 35

Slide 35 text

認可コードグラント

Slide 36

Slide 36 text

認可コードグラント OAuthの「クライアント」は、サーバーサイドのアプリ(コ ンフィデンシャルクライアント)とする。

Slide 37

Slide 37 text

認可コードグラント リソースオーナーに、ブラウザで「認可エンドポイント」 へアクセスさせる。

Slide 38

Slide 38 text

認可コードグラント 認可サーバの「認可エンドポイント」に、「認可リクエスト」を送る。 ======================================================== GET /auth ?response_type=code <= ”code” で「認可コードグラント」であることを知らせる &scope=xxx      <= アクセストークンのスコープ。アクセス範囲 &client_id=xxx     <= クライアントを特定するための「クライアント ID」 &redirect_uri=https%3A%2F%2Fexample%2Ecom%2Fdev%2Fcallback <=リダイレクトURIを指定 HTTP/1.1 Host: 認可サーバのドメイン ======================================================== ※「state」などの、GETパラメータを省略しています。 ※エンドポイントの「 /auth」パスは仮です。

Slide 39

Slide 39 text

認可コードグラント 認可サーバがログイン画面をユーザに表示。 認可サーバからしてみると、ユーザーごとに認可を管理したい場 合、ユーザーが自分のサービス上の「誰なのか」を特定する必要が ある。 ※認証方式はなんでも良い(指紋認証、顔認証、 etc) ※ここはOAuth2.0の仕様には書かれてはいない。

Slide 40

Slide 40 text

認可コードグラント ユーザが認証情報を入力して、認証ができたら、認可サーバは、「認可の確認 画面」を表示する。 ・「〇〇サービスへ△△へのアクセスを許可しますか?」 ・「〇〇サービスが△△へのアクセスを求めています。〇〇サービスがアクセ スできる情報(スコープ)を選択してください」 といった文言で表示される。

Slide 41

Slide 41 text

認可コードグラント ユーザが認可に同意したら、認可サーバは、「認可コード」を発行し、リ ダイレクトする。認可レスポンス。 Location: https://example.com/callback?code=xxxxxx

Slide 42

Slide 42 text

認可コードグラント ブラウザ経由でクライアントに戻ってくる。 クライアントに「認可コード」が渡る。

Slide 43

Slide 43 text

認可コードグラント クライアントは、認可サーバの「トークンエンドポイント」に、認可コードをつけてリクエストし、 「アクセストークン」を取得する。 ======================================================== POST /token HTTP/1.1 Host: 認可サーバのドメイン Content-Type: application/x-www-form-urlencoded grant_type=authorization_code <= ”authorization_code” で「認可コードグラント」である ことを知らせる &code=xxxx <= 認可コード ======================================================== ※リフレッシュトークンを使って、アクセストークンを再取得することが可能。(オプション) ※クライアントIDとクライアントシークレットが認可サーバに渡され、クライアント認証が実施さ れる。

Slide 44

Slide 44 text

認可コードグラント アクセストークンが取得できたので、クライアントはアクセストークンを使って、 リソースサーバにアクセスできるようになる。

Slide 45

Slide 45 text

認可コードグラント 以上、認可コードグラントの流れでした。 いくつか補足します。

Slide 46

Slide 46 text

認可コードグラント 認可コードグラントの特徴は、「認可コード」という「引換券」を使って、「アクセ ストークン」を取得するところ。

Slide 47

Slide 47 text

認可コードグラント クライアントからリダイレクトで、認可サーバにアクセスし、「認可コード」を取得 するまでは、クライアントを介していない! つまり、リソースオーナーのクレデンシャル(パスワードなど)は、クライアントに 渡っていない! 権限のスコープを絞った「アクセストークン」を渡すことで、限定的なアクセスを 提供できている。

Slide 48

Slide 48 text

インプリシットグラント - 一度のリクエストで、アクセストークンを発行。認可コードは出てこない。 - 現在は非推奨。 - パブリッククライアント向けのグラントタイプ。 - クライアントから認可サーバへのリクエストで、クライアントの認証が行われない。 - 識別のために、クライアント IDは送るが、シークレットは守れないので利用されない

Slide 49

Slide 49 text

インプリシットグラント

Slide 50

Slide 50 text

インプリシットグラント 「認可リクエスト」を送る。 ======================================================== GET /auth ?response_type=token <= ”token” で「インプリシットグラント」であることを知らせる &scope=xxx      <= アクセストークンのスコープ。アクセス範囲 &client_id=xxx     <= クライアントを特定するための「クライアントID」 &redirect_uri=https%3A%2F%2Fexample%2Ecom%2Fdev%2Fcallback <=リダイレクトURIを指定 HTTP/1.1 Host: 認可サーバのドメイン ======================================================== ※「state」などの、GETパラメータを省略しています。 ※エンドポイントの「/auth」パスは仮です。

Slide 51

Slide 51 text

インプリシットグラント 「認可への同意」までの流れは、認可コード グラントと同じ。

Slide 52

Slide 52 text

インプリシットグラント アクセストークンを、リダイレクトでクライアント に渡している。 「認可コード」は出てこない。

Slide 53

Slide 53 text

リソースオーナーパスワードクレデンシャルグラント - リソースオーナーのクレデンシャル(パスワードなど)が、クライアントを通して、認可サー バに送られる。 - 非推奨 - このグラントタイプが使えるのは、限定的なユースケース。 - リソースサーバと、認可サーバと、クライアントの提供元が同じ組織 。 - もしくはもともと、クライアントがユーザー ID、パスワードを保持する実装をしていて、 OAuthに対応する際に移 行するときのつなぎに利用。 - コンフィデンシャル、パブリッククライアント両方で利用可能。 同じ組織

Slide 54

Slide 54 text

リソースオーナーパスワードクレデンシャルグラント ※実際のGoogleのサービスがこうなっているということではなく、仮定の話です。

Slide 55

Slide 55 text

リソースオーナーパスワードクレデンシャルグラント ユーザのクレデンシャルを渡してしまう。 ※実際のGoogleのサービスがこうなっているということではなく、仮定の話です。

Slide 56

Slide 56 text

リソースオーナーパスワードクレデンシャルグラント ユーザのクレデンシャルを使って、アセクストークンを得 る。 アクセストークン取得後に、クライアントはユーザのクレデ ンシャルを破棄する。 ※実際のGoogleのサービスがこうなっているということではなく、仮定の話です。

Slide 57

Slide 57 text

クライアントクレデンシャルグラント - クライアント自体がリソースオーナー。 - アクセストークンの権限が、エンドユーザ単位ではなく、アプリ単位の時に利用でき る。 - また、クライアントがコンフィデンシャルクライアントの場合に利用できる。

Slide 58

Slide 58 text

クライアントクレデンシャルグラントの具体例 例: 画像識別サービスを使った、サーバサイドアプリ。 - エンドユーザーがアップした画像から、猫の種類を判定するようなアプリ。 - エンドユーザーごとに、画像識別サービス(リソースサーバ)へアクセスの権限を得る 必要がなく、サーバーサイド(リソースオーナー)のアクセス権だけあればいい。 OAuthのロールはここ 雑種!

Slide 59

Slide 59 text

クライアントクレデンシャルグラント

Slide 60

Slide 60 text

クライアントクレデンシャルグラント クライアントが、クライアントID、クライアントシークレットを 認可サーバに送る。 認可サーバがリソースオーナーであることを認証し、アク セストークンを返す。

Slide 61

Slide 61 text

以上、認可グラント4種類でした

Slide 62

Slide 62 text

もう一度整理 認可グラント名 特徴 代表的なクライアント 認可コード 認可コードを発行 ネイティブアプリ、SPA、サーバー サイドアプリ ※ただし、PKCEを使うべし。 インプリシット アクセストークンを直接発行 なし。使わない方がいい。 リソースオーナーパスワードクレデン シャル リソースオーナーのクレデンシャル をクライアントに直接渡す なし。使わない方がいい。 クライアントクレデンシャル リソースオーナーとクライアントが 同じ サーバーサイドアプリ(クレデン シャルクライアント) どの認可グラントも最終的に アクセストークンを取得する

Slide 63

Slide 63 text

OAuthのわかりづらいところを押さえる - 「クライアント」の意味を混同しやすい。 - ブラウザを経由して、行ったり来たりしている。 - 認可のための仕組みといいつつ、認証が出てくる。 - アクセストークンの他にも、認可コードやリフレッシュトークンといったものが出てく る。

Slide 64

Slide 64 text

「クライアント」の意味を混同しやすい。 - クライアントというと、ブラウザベースのWebアプリや、ネイティブアプリを思い浮か べがちだが、サーバーサイドアプリもOAuthのロールとしてのクライアントになりう る。 - OAuthのロールとしてのクライアントを意識するべし。

Slide 65

Slide 65 text

(認可コードグラントなどは)ブラウザを経由して、行ったり来た りしている なぜブラウザを経由する? 認可リクエスト時にクライアント内で、ユーザーのクレデンシャルを入力してしまうと、クラ イアントにユーザーのクレデンシャルが渡ってしまう。必然的にクライアント外(ブラウザ) でやりとりせざるを得ない。

Slide 66

Slide 66 text

認可のための仕組みといいつつ、認証が出てくる - サードパーティアプリ(クライアント)自体のユーザ認証 - 認可サーバで、リソースオーナーの認証 - OAuthのロールであるクライアントを認証(クライアントID、クライアントシークレット)

Slide 67

Slide 67 text

アクセストークンの他にも認可コードやリフレッシュトークンと いったものが出てくる - 俺たちが認可のために最終的に欲しいのは「アクセストークン」。まずこれを押さえ る。 - そのほかのコードや、トークンは次に覚える。 アクセストークン

Slide 68

Slide 68 text

パブリッククライアントでの認可コードグラント

Slide 69

Slide 69 text

よくある構成を考えてみる ネイティブアプリや、 JSアプリ(SPA)があって、バックエンドがあり、自社 のサービスを運用しているとする。よくある構成。

Slide 70

Slide 70 text

よくある構成を考えてみる この構成で、Googleや、twitter、LINEなど、 他のサービスとOAuthで連携したいとする。

Slide 71

Slide 71 text

よくある構成を考えてみる ネイティブアプリ、JSアプリから直接、連携した いAPI(リソースサーバ)を叩く。 この場合は、パブリッククライアント。

Slide 72

Slide 72 text

よくある構成を考えてみる バックエンドから連携したい API(リソースサーバ)を叩 く。 この場合は、コンフィデンシャルクライアント。

Slide 73

Slide 73 text

よくある構成を考えてみる ネイティブアプリ、JSアプリから直接連携したい API(リソースサーバ)を叩く場合と、 バックエンドから叩く場合が考えられる。 バックエンドの負荷対策など、要件によっては、パブリッククライアントにするか、コン フィデンシャルクライアントにするか検討する必要がある。

Slide 74

Slide 74 text

よくある構成を考えてみる パブリッククライアントを選んだとすると、認可コードグラントを利用することになるが、 先ほど説明した認可コードグラントのままでは、問題がある。 →ここを詳しく見ていく。 クライアントはネイティブアプリと仮定します。

Slide 75

Slide 75 text

パブリッククライアントでの認可コードグラント

Slide 76

Slide 76 text

パブリッククライアントでの認可コードグラント ネイティブアプリ(パブリッククライアント)での認可コードグ ラントをみていく。

Slide 77

Slide 77 text

パブリッククライアントでの認可コードグラント ネイティブアプリでOAuthスタート。 ネイティブアプリからブラウザが起動し、「認可リクエスト」が送られる。

Slide 78

Slide 78 text

パブリッククライアントでの認可コードグラント 認可サーバがログイン画面を表示し、ユーザー(リソースオーナー)の認証が 行われる。 認可画面を表示し、ユーザーが認可に同意して、 「認可コード」を認可レスポ ンスで返す。

Slide 79

Slide 79 text

パブリッククライアントでの認可コードグラント ブラウザ経由で、カスタムスキームでクライアントに「認可コード」が 渡る。 カスタムスキーム(カスタム URIスキーム):アプリが独自で定義す ることができるURIスキーム。 別のアプリから起動できるようにするもの。 例:myapp://oauth/callback

Slide 80

Slide 80 text

パブリッククライアントでの認可コードグラント クライアントは、認可サーバの「トークンエンドポイント」に、認可コードを つけてリクエストし、「アクセストークン」を取得する。

Slide 81

Slide 81 text

パブリッククライアントでの認可コードグラント 「アクセストークン」をクライアントが取得できたので、「アクセストークン」 を使ってリソースにアクセスする。

Slide 82

Slide 82 text

パブリッククライアントでの認可コードグラント ネイティブアプリ(パブリッククライアント)の認可コードグラントを見まし たが、脆弱性がある箇所があります。 さて、どこでしょうか。

Slide 83

Slide 83 text

パブリッククライアントでの認可コードグラント 「認可コード」を横取りできる状態になってい る。

Slide 84

Slide 84 text

認可コード横取り攻撃 悪意あるアプリをユーザーがインストール。 悪意あるアプリが本来のアプリと 同じカスタムスキーム を定義している。 ※カスタムスキームは重複が許されている。

Slide 85

Slide 85 text

認可コード横取り攻撃 同じカスタムスキームが設定された状態で、ほかのアプリからカスタムスキームで 連携されると、アプリの選択画面が出る。 ユーザーが攻撃者のアプリを選ぶと、「認可コード」が悪意あるアプリに渡ってしま う。

Slide 86

Slide 86 text

認可コード横取り攻撃

Slide 87

Slide 87 text

認可コード横取り攻撃 悪意あるアプリに「認可コード」が渡り、悪意あるアプリは 「アクセストークン」を取得できる。

Slide 88

Slide 88 text

認可コード横取り攻撃 「アクセストークン」を利用して、ユーザーのリソースを取 得できる。

Slide 89

Slide 89 text

認可コード横取り攻撃 クライアント認証情報(クライアント ID、クライアントシー クレット)を認可サーバに送信すれば、認可サーバがク ライアントを認証して、防げない?

Slide 90

Slide 90 text

認可コード横取り攻撃 パブリッククライアントは、ユーザの手元にソースがある ため、クライアント認証情報(クライアント ID、クライアント シークレット)を埋め込んでも、比較的簡単に取得できて しまう。

Slide 91

Slide 91 text

認可コード横取り攻撃 このままだと、認可サーバは、悪意あるアプリからのリク エストか、正常なアプリからのリクエストなのか判断がつ かない。

Slide 92

Slide 92 text

認可コード横取り攻撃 このままだと、認可サーバは、悪意あるアプリからのリク エストか、正常なアプリからのリクエストなのか判断がつ かない。

Slide 93

Slide 93 text

認可コードグラント+PKCE - PKCE(Proof Key for Code Exchange)を使って、「認可コード横取り攻撃」の対策 を行う。 - 認可リクエストの時に本来のアプリしか知り得ない情報を作成し、検証することで横 取りを防ぐ。

Slide 94

Slide 94 text

認可コードグラント+PKCE

Slide 95

Slide 95 text

認可リクエスト前に、クライアントで乱数 (code_verifier)を生成し保持する。 乱数 code_verifier 認可コードグラント+PKCE

Slide 96

Slide 96 text

認可コードグラント+PKCE 乱数から、特定の計算方法 (code_challenge_method)を使っ て、チャレンジ値(code_challenge)を生成する。 チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method

Slide 97

Slide 97 text

認可コードグラント+PKCE チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method 認可リクエスト時に、「計算方法」と、「チャレンジ値」を認可サーバに渡す。 計算方法 code_challenge_method チャレンジ値 code_challenge

Slide 98

Slide 98 text

認可コードグラント+PKCE チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method トークンリクエスト時に、クライアント内部で保存していた乱数を、認 可サーバに渡す。 計算方法 code_challenge_method チャレンジ値 code_challenge 乱数 code_verifier

Slide 99

Slide 99 text

認可コードグラント+PKCE チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method 認可サーバで、指定の計算方法でチャレンジ値を計算する。 保存していた方のチャレンジ値と一致しているか検証。 計算方法 code_challenge_method チャレンジ値 code_challenge チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method

Slide 100

Slide 100 text

認可コードグラント+PKCE チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method チャレンジ値が一致していたら、「アクセストークン」を返 す。 計算方法 code_challenge_method チャレンジ値 code_challenge チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method

Slide 101

Slide 101 text

認可コードグラント+PKCE チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method このとき、もし、悪意あるアプリに「認可コード」が渡ったとし ても。。 計算方法 code_challenge_method チャレンジ値 code_challenge チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method

Slide 102

Slide 102 text

認可コードグラント+PKCE チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method 悪意あるアプリは、元の「乱数」がわからないので、トークンリクエスト時に、適当に生成した 乱数を送ったとしても、チャレンジ値が一致しない! 認可サーバは、認可リクエストを送ってきたアプリであるかどうか判断がつく。 計算方法 code_challenge_method チャレンジ値 code_challenge チャレンジ値 code_challenge 乱数 code_verifier 計算方法 code_challenge_method

Slide 103

Slide 103 text

開発者視点でのOAuth

Slide 104

Slide 104 text

開発者視点から見ると クライアントを作る側。 認可サーバー(リソースサー バー)を作成する側。

Slide 105

Slide 105 text

クライアントを作る側 実装時にやること - OAuthクライアントの登録(リダイレクトURIの作成) - 要件に合わせた認可グラントの決定 - 認可コードグラントを選んだとして、パブリッククライアントにするか、コンフィデンシャルクライアントにするか - 認可エンドポイントへのリクエスト(ブラウザに飛ばす) - トークンエンドポイントへのリクエスト - アクセストークンの保存 - リソースサーバーへのアクセス etc…

Slide 106

Slide 106 text

クライアントを作る側 実装時にやること - OAuthクライアントの登録(リダイレクトURIの作成) - 要件に合わせた認可グラントの決定 - 認可コードグラントを選んだとして、パブリッククライアントにするか、コンフィデンシャルクライアントにするか - 認可エンドポイントへのリクエスト(ブラウザに飛ばす) - トークンエンドポイントへのリクエスト - アクセストークンの保存 - リソースサーバーへのアクセス etc… => 大きいサービスであれば、クライアント用のライブラリが存在するので、利用した方がベ ター。まずはしっかりドキュメントを読むこと。 ただし、サービスによっては非推奨であるインプリシットグラントが普通にガイドに書かれていた りするので、認可コードグラントにできないかなどの検討は必要。

Slide 107

Slide 107 text

認可サーバーを作る側 実装時にやること - OAuthクライアントの登録情報の管理 - サポートする認可フローの実装 - 認可エンドポイントの実装 - トークンエンドポイントの実装 - アクセストークンの管理(発行や破棄) - リソースサーバーでのアクセストークンの検証 - そもそも認証機能、認証画面や認可画面の作成 etc…

Slide 108

Slide 108 text

認可サーバーを作る側 実装時にやること - OAuthクライアントの登録情報の管理 - サポートする認可フローの実装 - 認可エンドポイントの実装 - トークンエンドポイントの実装 - アクセストークンの管理(発行や破棄) - リソースサーバーでのアクセストークンの検証 - そもそも認証機能、認証画面や認可画面の作成 etc… => やることが多い。認可サーバの実装ライブラリもあるが、 SaaSの選択肢もある。

Slide 109

Slide 109 text

その他補足 - 今回は説明を加えなかったが、OAuth2.0で見つかっている脆弱性対策、リスク低 減のために、リクエスト時にパラメータを付与することがあったり、アクセストークン などに有効期限といった扱いのルールがあるので注意。 - OAuth2.0は認可の仕組みだが、OAuth2.0を拡張した認証用の仕組みとして、 OpenIDConnectというものがある。

Slide 110

Slide 110 text

まとめ - OAuth 2.0 は認可の仕組み。 - OAuthのロール(登場人物の役割)とその関係性を意識し、自分が作成するクライ アントに対して適用し、適切な認可グラントを選びましょう - シーケンス図などを書いて整理すると、理解しやすいのでおすすめ - 利用するサービスのガイドをよく確認しよう - 基本的に自作はせずに、よくデバッグされた公開ライブラリを使うのがベター

Slide 111

Slide 111 text

参考文献 ・雰囲気で OAuth2.0 を使っているエンジニアが OAuth2.0 を整理して、手を動かしながら学べる本 , Auth屋, 2019 ・OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本 , Auth屋, 2019 ・OpenID Foundation Japan 翻訳. The OAuth2.0 Authorization Framework. https://openid-foundation-japan.github.io/rfc6749.ja.html, (2022/11/12) ・YouTube. OAuth & OIDC 入門編 by #authlete. https://www.youtube.com/watch?v=PKPj_MmLq5E, (2020/03/17) ・Qiita. OAuth2.0の認可レスポンスとリダイレクトに関する説明 . https://qiita.com/TakahikoKawasaki/items/8567c80528da43c7e844, (2022/11/12) ・Google Identity. Using OAuth 2.0 to Access Google APIs. https://developers.google.com/identity/protocols/oauth2, (2022/11/12)

Slide 112

Slide 112 text

ご清聴ありがとうございました!