個人開発をFirebase AuthとOIDC(OpenID Connect)でやることにしたので、OIDCについて勉強したメモ。
OAuth、OAuth認証、OpenID Connectの違いを整理して理解できる本 [2024年改訂版]
https://authya.booth.pm/items/1550861
個人開発でFirebase AuthのOIDCを使うことにしたのでざっくりとこれを読んだ。
自分の理解を試す文を書いてみる。
図はないし、仮に作っても丸パクリ以外にならないので書籍を購入して相互補完的に読んでほしい。
書籍による確認ももちろんしたが、
ChatGPTのo3-mini-highとo1に何度も何度もレビューさせたので大間違いはないはず…。
ひたすら「ラフでもいいから簡潔に書く」事を目指した。
OpenID Connectの核心
OIDCの核心は
「認証とは、ユーザーが何者かを確認するプロセスである」
「そのためにユーザーが送信したトークンとユーザーのIDの関連が必要である」
という認証に関する基本概念にある。
一方で、
「認可とは、何者かが既にわかっているユーザーに対して、権限を与えるプロセスである」
ということ。
また、
「認証をすることでそのユーザーが何者かがわかる。その結果、認可によってそのユーザーが持つ権限が手に入る」
という流れになる。認証は認可を含むというような単純な関係でもない。
認証をした後に認可の承認要求などが起きることもあるが、
基本的には認証プロセスの成功後、ユーザー権限の認可の条件を獲得している。
このため、OIDC認証において「ID」がコアな概念となる。
まず、OAuth2.0は、
- ユーザー
- クライアントアプリケーション
- (OAuth2.0におけるそういう用語だ。サーバーサイドである可能性もある)
- 認可サーバー
- リソースサーバー
の4者間の結構複雑な処理になる。
知らなくて良い情報を知らなくて良い対象に可能な限り送らないことでセキュアに保たれているということと、
あくまで「認可」であってIDに関する情報は持たないということがポイント。
また、なぜOAuth2.0では認証が安全に行えないのか(あるいはなぜOIDCがあるのか)は、
OAuth2.0による認証を無理やりやろうとするとなりすましができてしまうためである。
OAuth2.0で無理やり認証を実現する事の問題
まず、認可のアクセストークンはクライアントアプリケーションが手に入れることが可能。
バックチャネルによりそれを防ぐ仕組みもあるにはあるが、少なくともOAuth2.0は禁止してはいない。
裏を返せばクライアントアプリケーションはリソースサーバーのリソースを 認可されたスコープに関しては 取り放題だということ。
これについては事実上防ぎようがなく、諦める(仕様の対象外)というスタンスをOAuth2.0は取っている。
しかし、仮にそこでやり取りされるトークンが認証トークンだとしたら?
そのユーザーはもう認証済みだという扱いになり、
そのユーザーに可能なパスワードの変更、アカウントの削除、支払いに関する取引などのあらゆる危険な操作がやりたい放題になる。
この点において認可と認証は決定的に異なり、だから違う方法を取らなければならない。
そのため別の何かが必要だということだが、
OAuth2.0認証ではなく、OIDCが必要であることをはっきり示すこのような攻撃手法がある。
- 標的となるクライアントアプリケーションを操作するユーザーが悪意を持っていて
- ユーザー自身が運営するサービスにより、標的となるアプリの他のユーザーのOAuth2.0認証トークンを入手できた時
- 標的となるクライアントアプリケーションにログインする際、リダイレクト時にトークンをすりかえる操作をして
-
他のユーザーになりすます
事ができるという話で、
この問題は「標的となるクライアントアプリケーション」に責任がある、と捉えるのがOIDCの基本的な発想となる。
結論: OAuth2.0にIDを導入しよう。
そこでOIDCはクライアントアプリケーション(OIDCではリライングパーティと呼ぶ)がIDトークンを検証し、
- 認証プロセスの前段階とIDに関する矛盾がないか
のチェックに加えて、 - JWT署名が正当なものか
- nonceが正しく、リプレイ攻撃が起きてないか
- 対象クライアントが正しく、CSRFが起きてないか
などを含めてトークンを検証し、トークンのすり替え攻撃などの攻撃が起きないようなやり方を取っている。
それだけ、である。
もっと詳しい話はいくらでもあるが、
これ 「だけ」 で、OAuth2.0はOIDCになり、認可は認証として使えるようになる。
説明を簡単にするために大量に省略した詳細があるが、自分が理解した範囲ではこういう話。