OAuth 2.0 / OIDC と仲良くなりたい!
はじめに
私が所属するチームにおいて OAuth 2.0 および OIDC の理解は必要不可欠です。
そんなチームで開発していくために私が OAuth 2.0 / OIDC と仲良くなるためにこれまで学んできた経験を振り返っておこうと思います。
どんなことすれば OAuth 2.0 / OIDC と仲良くなれるのかなという参考にご活用ください。
そのため、この記事を読んでも OAuth 2.0 / OIDC と仲良くなれるというわけではありません。
ご了承ください。
私なりの OAuth 2.0 / OIDC の解釈
これまでの道のりを紹介していこうと思いますが、その前にいまの私の OAuth 2.0 / OIDC の解釈を記載しておこうと思います。
OAuth 2.0
OIDC
学びの道のり
とりあえず資料を読む
ガッチガチの仕様書を読んでもわからないのは明白だったので、巷で参考資料として共有されている記事を読みました。まったくわかりませんでした。いくら丁寧に解説されているところでわかりませんでした。
チームメンバーが作成していた資料があって共有いただき読みましたがなにもわかりませんでした。
前職では AWS Cognito を使って認証を実現していましたが全くなにもピンときませんでした。
zitadel/oidc との出会い
何気なく OpenID のサイトを見ていたら
zitadel/oidc というライブラリの存在を知りました。
私は Go が好きなので「とりあえずこれ触ったらなんかわかるかも」と思い手を動かしてみることにしました。
とりあえず誰か巻き込もう
前職の同僚を巻き込んで zitadel を fork してログ仕込みまくっていろいろ挙動を見ました。
以下の example の実装を使いました。
ログを仕込みまくって処理の流れを追ったり
認可コードフローシーケンス図を自分で書いたりしました、
リダイレクトがたくさん発生するので処理を追うのが難しかったです ...
別の前職同僚が OAuth徹底入門 で勉強している情報をキャッチ
私はこの人を結構信頼していたので声をかけました。教えてもらうために ...
ということで勉強会を開催しました。オンラインで開催し私含め4人で実施しました。
勉強会の流れは以下のようなものです。
1時間くらいの予定でしたが結局4時間くらい実施しました ...
- OAuth 2.0 に関する用語をできるだけ洗い出す
- 疑問点を洗い出す(腑に落ちていないこと)
- みんなで調べて整理する(各要素がなんのために存在しているのか考える)
- OAuth 2.0 の仕様書を眺める
- OAuth 2.0 まとめ
- OIDC に関する用語をできるだけ洗い出す
- 疑問点を洗い出す(腑に落ちていないこと)
- みんなで調べて整理する
- OIDC の仕様書を眺める
- OIDC まとめ
この勉強会を通じて一気に解像度が上がった気がします。
冒頭で記載した私なりの OAuth 2.0 / OIDC の解釈はこのときに整理したものです。
まだまだ理解は足りていない
今でもキャッチアップは続けてます。
以下のリポジトリでオレオレ認証基盤を開発して遊んでいます。
OIDC に対応できているかどうかを確認するために NextAuth.js を使ってます。
これと連携できれば OIDC に対応できてるってことでしょ?ってノリです。
ただ、内側の処理ちゃんとしていないのでたぶん脆弱性とかあります。
そのうちどこかにデプロイしたいと思っていますがまだまだローカル環境で遊んでいます。
(OIDCのフローを検証できるサイトがあった気がしたけどURLを忘れてしまいました ... )
おわりに
OAuth 2.0 / OIDC をキャッチアップしてて思うことって「これ考えた人まじで頭良いな」です。
攻撃方法とか見ていても「頭良いな」ってなります。
こんな流れで OAuth 2.0 / OIDC と仲良くなろうとしています。
この記事を書くにあたりチームメンバーへとレビューを受け更新し新たに認識したこともありました。
記事執筆大事ですね。
ちょっとは仲良くなれたかなって感じています。
OAuth 2.0 / OIDC と仲良くなりたい方はご参考まで!
Discussion
OAuthとOIDCの定義の部分にだけ補足させてください。
OAuth
委譲という用語は異常に難しいものです。
必ずしも委譲が行われない、自分のリソースにアクセスさせろというケースで利用する方法も定義されているので、"リソースアクセスを安全に実現するための仕組み" ぐらいで認識しておくほうが良いかもしれませんね。
リフレッシュトークンはアクセストークンを発行するためのものなので最終的な成果物はアクセストークンと捉えておくのが良いかと思います。
RFC6749はフレームワークの定義となっており、他に様々な仕様が存在しますが、全体を見ると
に集約されます。
OAuthにより解決したかった課題はBasic認証を用いたAPIアクセスのような "危険" なものを安全にすることでした。
このことから、上にも書いた通り、"リソースアクセスを安全にしたいから" の方が適切かもしれません。
クレデンシャルを預からず、範囲や期間を絞ったアクセストークンを利用する仕組みなので、"必要最低限の情報を保持したまま" といったところを意識していただけると良さそうです。
こちらは裏返しになるので、"必要最低限の情報を提供した上で" と言ったところを意識されると良いかと思います。
OIDC
"誰か" 以外に、
みたいなことをやり取りできる仕組みなので、
"その人の情報を教えるための決まりごと" ぐらいの認識でいると良いかと思います。
OIDCをIDトークンをやり取りする仕組みであると表現する方もいらっしゃいます。
上に書いた通り、ユーザーの情報を含む認証イベント全体の情報がIDトークンに含められます。
そして、非同期なタイミングでユーザーの最新情報を取得するため、OAuth 2.0で定義されているアクセストークンを使うエンドポイントが定義されているという感じですね。
OIDCはやり取りされるユーザー情報を利用して
などを実現したり、再認証などの用途に使える仕組みです。
"誰であるかが知って⚪︎⚪︎したいから" ぐらい踏み込んでいただけるとOIDCの仕様群の理解が進むかもしれません。
誰であるかを使ってログインに使ってもらいたい
誰であるか以外の情報をサービスに使ってもらいたい
これの大元に、そうやってユーザーの情報が他のサービスで幅広く使われることで
"自身のアカウントの価値を上げたい" "サービス群全体の利便性を上げたい"という目的というか期待があります。
長くなりましたが、この辺りを意識していただけるとプロトコルへの触れやすくなるかもしれないなという意図でコメントさせていただきました。
初学者や同じようなことを思っている開発者や何度も乗り越えてきた有識者が集まっているコミュニティもありますので、「何度調べてもここがわからない」「自分の理解が合っているかどうかわからない」みたいなことがあった場合はXなりこのような記事でアウトプットしてもらえたらサポートできると思います。