$30 off During Our Annual Pro Sale. View Details »

やさしく入門するOAuth2.0/easy-entry-oauth

marchin
November 17, 2022

 やさしく入門するOAuth2.0/easy-entry-oauth

marchin

November 17, 2022
Tweet

More Decks by marchin

Other Decks in Programming

Transcript

  1. やさしく入門するOAuth2.0

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  5. 認証と認可の違いは?

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  9. OAuth2.0とは

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  30. クライアントの事前登録

    View Slide

  31. 認可グラント

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  35. 認可コードグラント

    View Slide

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

    View Slide

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

    View Slide

  38. 認可コードグラント
    認可サーバの「認可エンドポイント」に、「認可リクエスト」を送る。
    ========================================================
    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」パスは仮です。

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  49. インプリシットグラント

    View Slide

  50. インプリシットグラント
    「認可リクエスト」を送る。
    ========================================================
    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」パスは仮です。

    View Slide

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

    View Slide

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

    View Slide

  53. リソースオーナーパスワードクレデンシャルグラント
    - リソースオーナーのクレデンシャル(パスワードなど)が、クライアントを通して、認可サー
    バに送られる。
    - 非推奨
    - このグラントタイプが使えるのは、限定的なユースケース。
    - リソースサーバと、認可サーバと、クライアントの提供元が同じ組織

    - もしくはもともと、クライアントがユーザー
    ID、パスワードを保持する実装をしていて、
    OAuthに対応する際に移
    行するときのつなぎに利用。
    - コンフィデンシャル、パブリッククライアント両方で利用可能。
    同じ組織

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  86. 認可コード横取り攻撃

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  94. 認可コードグラント+PKCE

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  103. 開発者視点でのOAuth

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  111. 参考文献
    ・雰囲気で 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)

    View Slide

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

    View Slide