OpenID
JWT

JWT/OpenID Connect に対する疑問

JWT を localStorage に保存して大丈夫?

<script src="//外部のCDN/jquery.js"></script><!-- 1 -->
<script src="トークンを扱う.js"></script><!-- 2 -->

ってすると取れそう?って思ったけど、ブラウザ内部に保存されるデータへのアクセスは、オリジンによって権限が分かれているクロージャでスコープ切ってる限りは大丈夫そう。

追記:オリジンはHTMLのオリジン。悪いスクリプトを読み込んじゃうとダメ。ちゃんと調査した後に、意図しない改変を防ぐために Subresource Integrity を使う。 integrity 属性でハッシュを付けて検証されるようにしよう。

RS256 ってどれぐらい強いの?

RFC 7518 によると、 RSASSA-PKCS1-v1_5 using SHA-256 。 いろんな機関の基準 をながめると、2048 bit の鍵を 1, 2 年に 1 回ぐらい鍵を更新しとけば 2030 年ぐらいまでは戦えるかも。適当に作ったシステムが意外と長く使われるのはよくある話なので、余裕を持ってより強い鍵を使っておいた方がたぶん良い。

鍵ってどうやって更新するの?

鍵を変更すると2種類の鍵で作られたトークンが世の中に存在することになる。検証時にキーを特定するには、"kid" (Key ID) Header Parameterを使ってキーを探す。古い鍵はしばらく検証のみに(非対称なら秘密鍵を失効)して、 "exp" クレームに設定した最後の期間を過ぎたら検証側も失効する。

Revoke ってどうしたら良い?

jti で区別して ブラックリストに入れる

DB へのアクセスが必要なくなるのがメリットの一つではあるが、マルチテナントを導入した時点で普通はキーをテナントごとに持つので、すでに考慮しなくても良いという主張。キャッシュを導入したり、非同期で配布して IO を追い出したりして最適化する。 exp を考慮すれば、貯まり続けるのも防げる。

特殊な状況でも無い限り、(ブラックリスト)⊂(全体のトークン)にはなるはずなので、セッションID方式に比べてまだメリットはあるかなと思う。

OpenID Connect トークンが二種類あるのはなぜ?

ジャストな回答

ID Token は JWT ですが、 Access Token に関しては IdP が独自に決められることが特に重要そう。
「RP が IdP を利用して End-User が本人か確認する」ことと、「RP が End-User の認可の下で IdP のリソースにアクセスできる」というのは、必ずしも一致しないという事情があるようです。認証を継続しつつ権限を変更とかが可能になりそう。