"仕様が読めるようになるOAuthとOpenID Connect入門"の質問への回答

2023/10/13に公開

ritouです。

某イベントのこの辺で出てくる質問に回答してみました。

https://www.youtube.com/watch?v=NyuaDiEd1ho&t=2922s

Q. SAMLとの違い
A. OAuthとは目的/用途が異なる。OIDCとの比較では、SAMLをモダンにしたのがOIDCという認識でおk。XML->JSON, XML Signature->JWTみたいな仕様の違いがある。あとはOIDCはSPAやモバイルアプリ、Verifiable Credentialsといった世の中の動向に追従して現在進行形で拡張仕様やプロファイル、ベストプラクティスの策定が進められている。

Q. 言葉の定義
A. 英語では決まっている。日本語に変換するときにおかしくなったり、IDaaSなどでOIDCをそのまま適用していない場合などで用語の混乱が起こりうる。

Q. 人間が介在しない認証フローではImplicit?非推奨?
A. おそらくClientCredentialsの方が適している

Q. Confidential ClientでもImplicitは使える?
A. 使えるかどうかは認可サーバーの実装次第。OAuth 2.0のImplicitはフロントチャンネルを経由するアクセストークンを安全に扱えないので使わないほうが良いのは明らか。

Q. OIDCではセッション管理不要?
A. OIDCはRP側のパスワード認証と並ぶような立ち位置であり、ログイン状態になった後のセッション管理の部分を置き換えるようなものではない。
IDaaSではその部分まで機能として提供しているものもあるが仕様の範囲外と言えるだろう。
OIDCのSession Managementなどの仕様はIdPのセッションが変わったかどうかの検知、ログアウトの同期といった機能はあるが、主に異なるドメイン間(IdP-RP間)のセッションの整合性を取るためのものであり、RPのセッション管理を代替するものであるとは言えないだろう。

https://ritou.hatenablog.com/entry/20151104/1446597256

Q. SPAなどでのIDTokenの扱い(SPA->バックエンドにIDTokenを送ってもいいか?バックエンドで全部やるのか?)
A. 実装としては両方あり得ると思うが安全性は当然異なる。まずはClientTypeの扱いが前者ではPublic、後者はConfidentialになる。前者はSPAだからそこでIDTokenまでとるんだ!と実装するケースと、IDaaSでSPA向けのドキュメントに従った結果そうなったなどのパターンがある。バックエンド側の検証はOIDCの仕様から外れる部分になるので、IDaaSなどの場合はそこをしっかりやる必要がある。
後者はトークンを受け取るところまでOIDCの仕様の対象となるので、比較的安全に実装可能。

https://zenn.dev/ritou/articles/d26c7861047a2d

Q. 管理画面からアクセストークンを発行する場合はClientCredentialsフロー?
A. 裏では同じことしてるとか、細けぇ話は認可サーバーによるかもしれない。フローになるのでしょうか?という問いに対しては、あくまで独自のショートカット的な立ち位置だと考えるのが良さそう。

Q. 有効期限のないアクセストークンとBasic認証の違い
A.
(1)クレデンシャルが送られる範囲
Client Credentials Flowでクレデンシャルが送られるのは認可サーバーのみ。リソースサーバーには送られない。
Basic認証では全てのリクエスト、つまりリソースサーバーにもクレデンシャルが送られるので違いがある
(2)Client Credentials Flowでは、アクセストークンにscopeなどを設定可能なので細かいアクセス管理が可能、アクセストークン単位での無効化が可能

Q. アクセストークン差し替えが可能ならOAuth 2.0全体の問題では?
A. フローの中で差し替えが可能なのはOAuth 2.0のImplicitフローがある。その辺り含めて安全にできないのでもう非推奨。それ以外のフロントエンド-バックエンド間の差し替えなどはアプリがわのセキュリティの話になるのでOAuth 2.0の問題とは言えないのではないか。Bearer Tokenの特徴を理解した上で安全に実装しましょう。

Q. 要件に合っている仕様があるかどうか不安
A. (必要であればお金を出して)詳しい人に聞きましょう

Q. 認可コードを一回かますのはなぜ?
A. Sender-Constrained Tokenという概念が必要。それを用いたリクエストの送信者を制限できるという意味合い。Confidential ClientであればClient Credentialsが必要だし、Public Clientの場合はそれができない分、PKCEで認可リクエスト生成時に保持しておいた値を利用しなければならない。この仕組みを入れることで安全にできる。

Q. GoogleはAccessTokenごとにscopeが管理されているか?
A. Googleはそう。このあたりは認可サーバーの実装に依存。

Q. OIDCのトークンの差し替えはないのか?
A. フロントチャンネルでトークンが流れる場合は起こり得る。そのため、nonceの値や一緒に送られるトークンのハッシュ値などを利用した検証方法が用意されていることがOAuth 2.0との違いと言える。フロントエンド-バック

Q. リフレッシュトークンの差し替え?
A. リフレッシュトークンも上述のSender-Constrained Tokenであり、これを利用してアクセストークンを取得するためにはClientCredentialsが必要なところはアクセストークンと違う。

Q. IDトークンの署名検証は必要?
A. なるべくサーバー間通信で取得しつつ、どうしてもフロントチャンネル(リダイレクト)で受け取る、フロントエンド-バックエンドでやりとりする場合は署名検証を行う必要がある。

Q. OIDCでも認可コード?
A. あんまり気にしなくていいと思う。

Q. アクセストークンをJWTにして検証するとかはあり?
A. 基本的にクライアントはアクセストークンを検証すべきではない。OIDCが使えない場合はあるかもしれないが、それはもう仕様対象外。あと、検証が必要ない、つまり置き換えが発生しないような実装をしましょう。

https://ritou.hatenablog.com/entry/2023/10/08/215035

ではまた。

https://twitter.com/ritou/status/1713496809694474522

Discussion