🔐

OAuth 2.0 / OIDC と仲良くなりたい!

2023/12/28に公開1

はじめに

私が所属するチームにおいて 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

https://openid-foundation-japan.github.io/rfc6749.ja.html

OIDC

https://openid-foundation-japan.github.io/openid-connect-core-1_0.ja.html

学びの道のり

とりあえず資料を読む

ガッチガチの仕様書を読んでもわからないのは明白だったので、巷で参考資料として共有されている記事を読みました。まったくわかりませんでした。いくら丁寧に解説されているところでわかりませんでした。
チームメンバーが作成していた資料があって共有いただき読みましたがなにもわかりませんでした。
前職では AWS Cognito を使って認証を実現していましたが全くなにもピンときませんでした。

zitadel/oidc との出会い

何気なく OpenID のサイトを見ていたら

https://openid.net/developers/certified-openid-connect-implementations/

zitadel/oidc というライブラリの存在を知りました。

https://github.com/zitadel/oidc

私は Go が好きなので「とりあえずこれ触ったらなんかわかるかも」と思い手を動かしてみることにしました。

とりあえず誰か巻き込もう

前職の同僚を巻き込んで zitadel を fork してログ仕込みまくっていろいろ挙動を見ました。
以下の example の実装を使いました。

https://github.com/zitadel/oidc/tree/main/example

ログを仕込みまくって処理の流れを追ったり

認可コードフローシーケンス図を自分で書いたりしました、

リダイレクトがたくさん発生するので処理を追うのが難しかったです ...

別の前職同僚が OAuth徹底入門 で勉強している情報をキャッチ

https://www.shoeisha.co.jp/book/detail/9784798159294

私はこの人を結構信頼していたので声をかけました。教えてもらうために ...
ということで勉強会を開催しました。オンラインで開催し私含め4人で実施しました。

勉強会の流れは以下のようなものです。
1時間くらいの予定でしたが結局4時間くらい実施しました ...

  1. OAuth 2.0 に関する用語をできるだけ洗い出す
  2. 疑問点を洗い出す(腑に落ちていないこと)
  3. みんなで調べて整理する(各要素がなんのために存在しているのか考える)
  4. OAuth 2.0 の仕様書を眺める
  5. OAuth 2.0 まとめ
  6. OIDC に関する用語をできるだけ洗い出す
  7. 疑問点を洗い出す(腑に落ちていないこと)
  8. みんなで調べて整理する
  9. OIDC の仕様書を眺める
  10. OIDC まとめ

この勉強会を通じて一気に解像度が上がった気がします。
冒頭で記載した私なりの OAuth 2.0 / OIDC の解釈はこのときに整理したものです。

まだまだ理解は足りていない

今でもキャッチアップは続けてます。
以下のリポジトリでオレオレ認証基盤を開発して遊んでいます。

https://github.com/otakakot/ninshow

OIDC に対応できているかどうかを確認するために NextAuth.js を使ってます。
これと連携できれば OIDC に対応できてるってことでしょ?ってノリです。
ただ、内側の処理ちゃんとしていないのでたぶん脆弱性とかあります。
そのうちどこかにデプロイしたいと思っていますがまだまだローカル環境で遊んでいます。
(OIDCのフローを検証できるサイトがあった気がしたけどURLを忘れてしまいました ... )

おわりに

OAuth 2.0 / OIDC をキャッチアップしてて思うことって「これ考えた人まじで頭良いな」です。
攻撃方法とか見ていても「頭良いな」ってなります。
こんな流れで OAuth 2.0 / OIDC と仲良くなろうとしています。

この記事を書くにあたりチームメンバーへとレビューを受け更新し新たに認識したこともありました。
記事執筆大事ですね。

ちょっとは仲良くなれたかなって感じています。

OAuth 2.0 / OIDC と仲良くなりたい方はご参考まで!

Discussion

ピン留めされたアイテム
ritouritou

OAuthとOIDCの定義の部分にだけ補足させてください。

OAuth

OAuth 2.0 ってなに?
・権限を委譲するための決まりごと

委譲という用語は異常に難しいものです。
必ずしも委譲が行われない、自分のリソースにアクセスさせろというケースで利用する方法も定義されているので、"リソースアクセスを安全に実現するための仕組み" ぐらいで認識しておくほうが良いかもしれませんね。

OAuth 2.0 での成果物は?
・アクセストークン
・リフレッシュトークン

リフレッシュトークンはアクセストークンを発行するためのものなので最終的な成果物はアクセストークンと捉えておくのが良いかと思います。

RFC6749はフレームワークの定義となっており、他に様々な仕様が存在しますが、全体を見ると

  • アクセストークンを発行する方法
  • そのアクセストークンを利用する方法

に集約されます。

OAuth 2.0 はなぜ必要?
・ユーザーのクレデンシャル管理を楽にしたいから

OAuthにより解決したかった課題はBasic認証を用いたAPIアクセスのような "危険" なものを安全にすることでした。

このことから、上にも書いた通り、"リソースアクセスを安全にしたいから" の方が適切かもしれません。

使う側
・誰かのリソースを使ってサービスを開発したいから

クレデンシャルを預からず、範囲や期間を絞ったアクセストークンを利用する仕組みなので、"必要最低限の情報を保持したまま" といったところを意識していただけると良さそうです。

作る側
・自分のリソースを使ってサービスを開発してもらいたいから

こちらは裏返しになるので、"必要最低限の情報を提供した上で" と言ったところを意識されると良いかと思います。

OIDC

OIDC ってなに?
・その人が誰であるかを教えるための決まりごと

"誰か" 以外に、

  • どんな属性情報を持っているか
  • OPにいつ、どのような認証方式でログインしたのか
  • どのような本人確認などを済ませているのか

みたいなことをやり取りできる仕組みなので、

"その人の情報を教えるための決まりごと" ぐらいの認識でいると良いかと思います。

OIDC での成果物は?
・アクセストークン
・リフレッシュトークン
・IDトークン

OIDCをIDトークンをやり取りする仕組みであると表現する方もいらっしゃいます。
上に書いた通り、ユーザーの情報を含む認証イベント全体の情報がIDトークンに含められます。

そして、非同期なタイミングでユーザーの最新情報を取得するため、OAuth 2.0で定義されているアクセストークンを使うエンドポイントが定義されているという感じですね。

使う側
・誰かのリソースを使ってサービスを開発したいから
・誰かのサービスの誰であるかが知りたいから

OIDCはやり取りされるユーザー情報を利用して

  • 新規登録時の簡略化
  • ログイン
  • 属性情報の同期

などを実現したり、再認証などの用途に使える仕組みです。

"誰であるかが知って⚪︎⚪︎したいから" ぐらい踏み込んでいただけるとOIDCの仕様群の理解が進むかもしれません。

作る側
・自分のリソースを使ってサービスを開発してもらいたいから
・自分のサービスで誰であるかを知ってもらいたいから

誰であるかを使ってログインに使ってもらいたい
誰であるか以外の情報をサービスに使ってもらいたい

これの大元に、そうやってユーザーの情報が他のサービスで幅広く使われることで
"自身のアカウントの価値を上げたい" "サービス群全体の利便性を上げたい"という目的というか期待があります。

長くなりましたが、この辺りを意識していただけるとプロトコルへの触れやすくなるかもしれないなという意図でコメントさせていただきました。

初学者や同じようなことを思っている開発者や何度も乗り越えてきた有識者が集まっているコミュニティもありますので、「何度調べてもここがわからない」「自分の理解が合っているかどうかわからない」みたいなことがあった場合はXなりこのような記事でアウトプットしてもらえたらサポートできると思います。