※当サイトの記事には、広告・プロモーションが含まれます。

Spring Authorization Serverは実用に耐え得るものになったのか?

www.itmedia.co.jp

biz-journal.jp

 今回注目されているのが、同じタイミングでイギリス、オーストラリア、韓国、台湾、香港、タイ、カナダ、ドイツ、ニュージーランドなど海外のマクドナルド店舗でも同様の障害が発生したという点だ。

マクドナルド・システム障害、世界で同時発生→店舗も臨時休業の「複雑な原因」 | ビジネスジャーナル

⇧ う~む、システムを疎結合に維持するのが如何に難しいのかが証明された良い事例ですな。

とは言え、

jp.reuters.com

イアン・ボーダン最高財務責任者(CFO)は、海外のフランチャイズ店は中国、インド、日本、ブラジルなどでおよそ7000店を新規に開くと説明した。これらにより、同社の全店舗数は27年までに5万店前後に達する。

マクドナルド、27年までに世界で1万店新規開設 過去最速の拡大 | ロイター

⇧ 流石に、この店舗数の設定変更を個別にするわけにはいかないと思うけど、せめて地域毎に設定を分割することはできなかったんかね?

日本の外務省の公開している資料だと、

www.mofa.go.jp

⇧ 上図のように、大きく分けて7つの地域に分類しているっぽいので、設定を変更するにしろ、地域毎に設定を分けておけば、設定変更については7回の作業で済むわけだから、そのぐらいの作業工数は許容しても良い気はするんですけどね。

設定を分けて変更を適応するようにしておけば、少なくともシステム全体に障害が波及するのを防げる可能性があるわけですし。

サードパーティー製システム」の設定変更作業で起きた障害と言っているので、「サードパーティー製システム」の設定変更について、地域毎に設定を分割して変更を実施可能であるという前提の話になりますけど。

OpenID ConnectのAuthorization Serverは外部サービスを使う?

前に、

ts0818.hatenablog.com

⇧ 上記の記事で、「OAuth 2.0」で脆弱性を排除した「認証」「認可」を実現するには、

 \mathsf{ OAuth } \ \mathsf{ 2.0 } \ + \ \mathsf{ OpenID } \ \mathsf{ Connect}

を実現する必要がありそうということで、整理していた中で、

No OAuth 2.0 OpenID Connect
1 Resource Owner Resource Owner
2 User Agent User Agent
3 Client RP(Relying Party)
4 Authorization Server IdP(Identity Provider) Authorization Server
5 Resource Server UserInfo Endpoint

⇧ 上記のような登場人物が出てくることが分かり、「OpenID Connect」の「Authorization Server」が「ID Token」を扱うことができる必要があることが分かりましたと。

ただ、「OpenID Connect」系の仕様書には、「IdP(Identity Provider)」って言葉は出て来ないんよな...

openid.net

1.3. Overview

The OpenID Connect protocol, in abstract, follows the following steps.

  1. The RP (Client) sends a request to the OpenID Provider (OP).
  2. The OP authenticates the End-User and obtains authorization.
  3. The OP responds with an ID Token and usually an Access Token.
  4. The RP can send a request with the Access Token to the UserInfo Endpoint.
  5. The UserInfo Endpoint returns Claims about the End-User.

https://openid.net/specs/openid-connect-core-1_0.html

These steps are illustrated in the following diagram:

https://openid.net/specs/openid-connect-core-1_0.html

⇧「OpenID Provider(OP)」とあるので、無理やり「IdP(Identity Provider)」っぽい表記にすると「OIdP(Open Identity Provider)」とはなるけど...

で、この「OpenID Connect」の「Authorization Server」の部分について、

siddhivinayak-sk.medium.com

To perform Authentication on OpenID Connect, we need an Authorization server. There are multiple third-party Authorization server available from different software vendors like Google, Facebook, Twitter etc. Here for demonstration purpose, embedded Keycloak has been used.

https://siddhivinayak-sk.medium.com/openid-connect-authentication-and-oauth-2-0-authorization-in-web-application-e7e422eb5223

⇧ ネットの情報だと、外部のライブラリに委譲する感じになってくるらしい。

Spring Authorization Serverは実用に耐え得るものになったのか?

まずは、「Spring Authorization Server」についての説明を確認。

github.com

The Spring Authorization Server project, led by the Spring Security team, is focused on delivering OAuth 2.1 Authorization Server support to the Spring community.

This project replaces the Authorization Server support provided by Spring Security OAuth.

https://github.com/spring-projects/spring-authorization-server

⇧ とありますと。

「OAuth 2.1」はと言うと、

valinux.hatenablog.com

OAuth 2.1 は新たなプロトコルを定義するものではなく、OAuth 2.0 および関連する RFC やドラフトを整理し、OAuth の良いプラクティスを示すものとして位置づけられているようです。

OAuth 2.1 のドラフトから OAuth 2.0 のプラクティスを学ぶ - VA Linux エンジニアブログ

OAuth 2.0 と OAuth 2.1 の違い

OAuth 2.0 と OAuth 2.1 の違いは、draft (The OAuth 2.1 Authorization Framework) の Section 10 に列挙されており、6つの違いがあると示されています。

  1. Authorization Code grant フローでは PKCE を標準で使用する
  2. リダイレクトURIの検証は文字列の完全一致で行わなければならない
  3. Implicit grant フローは仕様から除去される
  4. Resource Owner Password Credentials grant フローは仕様から除去される
  5. Bearer トークンをURIのクエリ文字列として渡す方法は仕様から除去される
  6. パブリッククライアントでは、リフレッシュトークンを利用できる送信者または利用回数を制限する

OAuth 2.1 のドラフトから OAuth 2.0 のプラクティスを学ぶ - VA Linux エンジニアブログ

⇧「OAuth 2.0」と「OAuth 2.0」に関連するドキュメントの整理が目的らしいですと。

まぁ、確かに、「OAuth 2.0」の中で脆弱性のあるフローが放置されていたのは宜しくなかったのだけど、何故、もっと早い段階で整理しなかったのかというのと、「OAuth 2.0」から「OAuth 2.1」にバージョン変えるのってどうなのかね?

「Spring Authorization Server」のドキュメントも、「OAuth 2.1(旧:OAuth 2.0)」みたいな感じで「OAuth 2.0」との関係が分かるようにしておいて欲しいですな...

そもそもとして、「OAuth 2.1」って、未だ「draft」の段階という状態のような気がするんだが、そのあたりの状況ってどうなっているんですかね?

「OAuth 2.1」は「OAuth 2.0」をベースにしているということで、「OAuth 2.1」と「OAuth 2.0」の差分以外は、これまで通り「OAuth 2.0」の内容と変わらないと。

前置きが長くなりましたが、

qiita.com

⇧ 上記サイト様によると「Spring Authorization Server」のプロジェクトが発足されて間もない段階では、実用に耐え得る代物ではなかったようです。

上記サイト様の中のやり取りで、槙 俊明さん(Springプロジェクト関連の書籍とか出してる。)が「Spring Authorization Server」のレビュー的なものを依頼してるのですが、これは、槙さんが悪い気がする。

そもそも、Springのプロジェクトを自分たちで利用してナレッジを公開するべきだと思うし、自分たちで理解できていなくて使いこなせていない状態のまま公開するのが間違っている気はするので(開発した機能を検証すべきだと思う)、まずは、Springのプロジェクトの開発に関わっている人たちがナレッジを共有するべきな気がするんですけどね、

spring.pleiades.io

⇧ 一応、有償サポートもしてるみたいですし。

まぁ、優先順位付けの前に、「Authorization Server」としての要件を満たすためのタスクが洗い出せているのか、何が残タスクとなっているのかについての整理が必要な気がしますけど...

ライブラリを利用する側からしたら、本番環境(商用環境)での実用に耐え得る状態なのかが一番知りたいことだと思うんですけど、「Spring Authorization Server」については、そのあたりの状況が見え辛いんですよね...

一応、

github.com

⇧ タスクボードで管理はしてるっぽいのですが...

脱線しましたが、上記のような経緯があったらしいので、てっきり槙さんが「Spring Autorization Server」の実装例を公開してくれているものと思いきや、2024年3月18日(月)時点でそのような情報は見当たらなかったので、残念ながら、「Spring Autorization Server」は実用に耐え得る代物になっていないのかもしれない。

ナレッジの共有をしていきませんか、と提案するからには、言い出した人が率先してナレッジを共有してくれると思ってしまったんだが、う~む、IT業界の文化というものがよく分からんですな...

そもそもとして、

zenn.dev

※ Spring Authorization Server は Spring 3系のみ対応

Spring Authorization Server を使って簡単な IdP を作ってみる

zenn.dev

zenn.dev

⇧ 上記サイト様の情報を見ると、今のところ「Spring Authorization Server」が「response_type」として「code」にしか対応できていないらしいんですよね...

あと、「Spring Boot 3.x」が必須らしいですな。「Spring Boot 3.x」は、Java 17以上である必要もあるので、Java 17より以前のバージョンを使っている環境だと、導入できないってことになりますな。

stackoverflow.com

⇧ 上記サイト様によりますと、「Spring Authorization Server」は「OAuth 2.1」をサポートする方針だからということを仰っている方がおられたのですが、

qiita.com

RFC 6749 は認可エンドポイントという Web API を定義しています。 この API は必須のリクエストパラメーターとして response_type を要求します。 OpenID Connect は、この response_type の仕様を拡張することにより ID トークン発行手順を定義しました。

OpenID Connect 全フロー解説 #OAuth - Qiita

RFC 6749 の時点では response_type が取りうる値は code か token のどちらかでしたが、OpenID Connect では、id_token という新しい値を追加した上で、codetokenid_token の任意の組み合わせを response_type に指定してもよいことにしました。 加えて、none という特殊な値も定義しました。 この結果、response_type は次の値を取りうることになりました。

OpenID Connect 全フロー解説 #OAuth - Qiita

⇧ そもそもとして、「OAuth 2.0」ないし「OAuth 2.1」の仕様では「response_type」の値として「id_token」が考慮されていないので、「Spring Authorization Server」は「ID Token」に対応する気が無いってことなんかね?

Authleteの方の説明によると、「ID Token」を利用するには、

logmi.jp

OpenID Connect Coreという仕様の3.1.2.1のAuthentication Requestを見ると、scopeの値としてOpenID Connectリクエストはopenidというscopeを含める必要がある。openidというscopeの値が含まれていない場合は、その動作は未定義であるという感じです。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

仕様の「the behavior is entirely unspecified」という文章に、私は正しく動かないという解釈をしました。しかし世の中には正しく動くケースを含むと考える人もいます。これはOAuthのメーリングリストで議論を吹っ掛けてこういう話が出たんですけど、正しく動いてよいなら「MUST contain」と仕様書に書く意味がないと僕は思います。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

あるかどうかをチェックしなくていいのだったら認可サーバーの実装でscopeにopenidが含まれているかどうかチェックする必要がなくなる。なのでAuthleteの実装としては、response_typeがid_tokenが含まれている場合、scopeにopenidが含まれていなければ必ずエラーしています。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

response_typeがcode、token、code token、noneの場合、scopeにopenidが含まれていなくてもエラーにはならない。要はresponse_typeにid_tokenが含まれていない場合はエラーにならない実装になっています。だからここら辺は認可サーバーの実装者の哲学とかが反映されたりするんですよね。仕様をどう解釈しているか。Authleteはこういう実装になっています。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

OpenID Connectの仕様になっているので、組み合わせ的にはこういうことが発生し得るんですね。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

response_typeの値とscopeの値がopenidを含むかどうか。これはここに組み合わせ爆発みたいになっていますが、一番多いのがこの7番で、response_typeにcodeやid_token、tokenも含まれている。そしてscopeにopenidが含まれている状態。こんな感じの組み合わせで変わります。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

⇧ 上記のように「OpenID Connect」の仕様を実装する必要がありそうなのだけど、「Spring Authorization Server」は、「OpenID Connect」を利用しない方針に舵を切ったということなのだろうか?

「Spring Authorization Server」の実装の方針がいまいちよく分からないのですが、「OpenID Connect」の仕様に対応した「Authorization Server」の選定として、

logmi.jp

なので、認可サーバーの実装としてはIDトークンの署名はできても暗号化はできないという実装はけっこうあります。認可サーバーの製品を選ぶときにIDトークンの暗号化はできるのかどうかチェックしたほうがいいです。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

例えばFinancial-grade APIという、よりセキュアな仕様だと逆にRS256は使ってはいけないとなっているんです。ES256かPS256のどちらかでないといけないと書かれているので、そこをサポートしていない認可サーバーを選ぶと、将来的にFinancial-grade APIのサポートは無理になってしまいます。そこはアルゴリズムの注意点ですね。

OpenID Connectのフローや、JWKやPKCEについて解説 - ログミーTech

⇧「ID Token」に対しての暗号化アルゴリズムに対応してくれているかどうかもチェックした方が良いようです。

ちなみに、「OAuth 2.0」ないし「OAuth 2.1」の仕様に出てくる「PKCE(Proof Key for Code Exchange by OAuth Public Clients)」については、

qiita.com

PKCEの限界

ちょっと話がそれますが、PKCEで対策できる範囲には限界があります。PKCEは、攻撃者のアプリが最初のcode_challengeハッシュの元になった値を知らないことが前提になっています。

OAuth2.0 PKCEとは 〜Stateとの違い〜 #OAuth2.0 - Qiita

ということは、予測できる値(同じ値を使用する等)の場合は、このフローを使用していても認可コード横取り対策にはなりません。

OAuth2.0 PKCEとは 〜Stateとの違い〜 #OAuth2.0 - Qiita

これはOAuth2.0の限界だと思っているのですが、どんなに最新仕様を認可サーバ側に実装しても、クライアント側の実装に委ねているため、絶対に守れるものでは無いと考えて設計すべきかと思います。

OAuth2.0 PKCEとは 〜Stateとの違い〜 #OAuth2.0 - Qiita

⇧ 上記サイト様によりますと、限界があるらしい...

OpenID Connect」の仕組みも「RP(Relying Party)」は、「Authorization Server」から見たらクライアント側にあたると思うんだが、「PKCE(Proof Key for Code Exchange by OAuth Public Clients)」のようなセキュリティリスクは残るということですかね?

とりあえず、2024年3月18(月)時点だと、「Authorization Server」として「Spring Authorization Server」を本番環境(商用環境)で利用するのは時期尚早という感じになるのかな?

ちなみに、

qiita.com

2018 年 11 月 30 日に『犯罪による収益の移転防止に関する法律』(犯罪収益移転防止法/犯収法)を改正する命令が公表されました。この改正で「オンラインで完結する自然人の本人特定事項の確認方法の追加」が行われ、eKYC(electronic Know Your Customer)の根拠法となりました。

Identity Assurance - eKYC 時代の OpenID Connect #openid_connect - Qiita

そして、当改正から約一年後の 2019 年 11 月 11 日、世界標準仕様策定団体である OpenID Foundation から『OpenID Connect for Identity Assurance 1.0』という技術仕様の第一版公開されました。また、これを受けて同団体内に新たに『eKYC and Identity Assurance ワーキンググループ』が設置されました。それから約半年後の 2020 年 5 月 19 日には、同仕様の第二版公開されました。

Identity Assurance - eKYC 時代の OpenID Connect #openid_connect - Qiita

犯収法改正と当技術仕様の策定は独立事象ですが、トラストレームワークの一種として日本の犯収法を表す jp_aml という値が同仕様書で定義されるなど(Trust Frameworks)、関連性が認められます。

Identity Assurance - eKYC 時代の OpenID Connect #openid_connect - Qiita

qiita.com

OpenID Connect for Identity Assurance 1.0 (OIDC4IDA または IDA) は、OpenID Foundation の eKYC-IDA ワーキンググループが開発した技術仕様です。当仕様は OAuth 2.0 と OpenID Connect (OIDC) を基盤とし、自然人の検証済みクレームを格納する JSON 構造を定義します。

実装者による OIDC4IDA 解説 #openid_connect - Qiita

インターネット上にはユーザー登録可能なウェブサービスがたくさんあります。それらの多くは属性情報の登録をユーザーに求めますが、登録されるデータはユーザーが自己申告したものに過ぎず、法的な文脈では利用できません。ここで OIDC4IDA が登場します。

実装者による OIDC4IDA 解説 #openid_connect - Qiita

⇧ 上記サイト様にある説明を見た感じでは、法的な文脈において「ユーザーの識別」を担保する仕組みとして、「OpenID Connect for Identity Assurance 1.0 (OIDC4IDA または IDA) 」という仕様が策定されているらしいので、「Spring Authorization Server」の開発方針の詳細が分からんのだけど、「OpenID Connect」の仕様を実装しておいて欲しい気持ちはあるのだけど、「Spring Authorization Server」のREADMEには、「OpenID Connect」の言葉が出て来ないんよな...

ただ、

docs.spring.io

⇧ 機能一覧には、「OpenID Connect」に関する情報が出てきていて、「Spring Authorization Server」の方針がよく分からん...

毎度モヤモヤ感が半端ない...

今回はこのへんで。