はじめに
OpenID Connect Core 1.0 仕様に id_token_hint という認可リクエストパラメータが定義されています。しかし、実は Authlete はこのリクエストパラメータをサポートしていません。
2014 年の Authlete の初期実装コードに
// TODO: id_token_hint
と書いてから 10 年以上経過しましたが、未だにこのパラメータを処理するコードは Authlete の実装内に存在しません。
過去に何度か id_token_hint パラメータのサポートについて問い合わせを受けたことがありましたが、あまり理由を説明せずに「サポートしていません」という回答をしていました。社内の Slack でも「宗教上の理由でサポートしていない」と言い、理由は説明していませんでした。
しかし最近、社内から「宗教上の理由」を知りたいとの声が上がったので、説明することにしました。
id_token_hintをサポートしない理由
以下、社内の Slack に私が投稿した説明です。
用途を考えると、
id_token_hintには古い ID トークンが指定されます。この ID トークンは、既に期限切れしていたり (=expクレームの値が現在時刻より古い)、その署名を検証するための公開鍵が入手できなくなっていたりする可能性があります。id_token_hintを使うということは、技術的には、ID トークンの有効期限や署名を無視して ID トークン内のsubクレームの値を参照するということを意味します。この、「有効期限や署名を無視する」という処理が実装者として賛同しがたく、また、
id_token_hintをサポートしても、できることがせいぜい「出所不明のsub値をログイン時のヒントとして使う」ことしかないので、(場合によっては古い署名検証鍵をid_token_hintのためだけに保持する等の) 実装の労力に対して得られるメリットはごくわずかです。このような理由で、id_token_hintをサポートしていません。
id_token_hintの仕様を策定した方々の意図は知りませんが、彼らは「有効期限や署名を無視する」という処理を想定していたのかもしれません。しかし、その処理については、私がそうであるように、反対意見もあるでしょう。つまり、人によって意見が分かれることが考えられます。このように意見が分かれうるので、「宗教上の理由」と表現しています。
OIDC Core 1.0 は login_hint というリクエストパラメータも定義しています。この login_hint のほうが柔軟性が高い (値のフォーマットに縛りがない) ため、なおさら id_token_hint を使う理由がありません。
署名検証ができないせいで出所不明となっている ID トークンのペイロードからわざわざ sub クレームの値を取り出すくらいなら、login_hint パラメータの値をそのまま利用すればよい、と思うわけです。
参考:仕様による定義
id_token_hint
OPTIONAL. ID Token previously issued by the Authorization Server being passed as a hint about the End-User's current or past authenticated session with the Client. If the End-User identified by the ID Token is already logged in or is logged in as a result of the request (with the OP possibly evaluating other information beyond the ID Token in this decision), then the Authorization Server returns a positive response; otherwise, it MUST return an error, such as login_required. When possible, an id_token_hint SHOULD be present when prompt=none is used and an invalid_request error MAY be returned if it is not; however, the server SHOULD respond successfully when possible, even if it is not present. The Authorization Server need not be listed as an audience of the ID Token when it is used as an id_token_hint value.
If the ID Token received by the RP from the OP is encrypted, to use it as an id_token_hint, the Client MUST decrypt the signed ID Token contained within the encrypted ID Token. The Client MAY re-encrypt the signed ID token to the Authentication Server using a key that enables the server to decrypt the ID Token and use the re-encrypted ID token as the id_token_hint value.
audience (aud クレームの値) がクライアントになっている ID トークンを認可サーバに投げ返したり、発行された ID トークンが暗号化されている場合は id_token_hint として使う前に暗号を解く必要がある (そして結果として暗号化されていない ID トークンをフロントチャネルを通して認可サーバに投げ返すので暗号化していた意味がなくなる) など、ID トークンの流用さ加減が半端ありません。 (注:個人による宗教上の見解です)
login_hint
OPTIONAL. Hint to the Authorization Server about the login identifier the End-User might use to log in (if necessary). This hint can be used by an RP if it first asks the End-User for their e-mail address (or other identifier) and then wants to pass that value as a hint to the discovered authorization service. It is RECOMMENDED that the hint value match the value used for discovery. This value MAY also be a phone number in the format specified for the phone_number Claim. The use of this parameter is left to the OP's discretion.
おわりに
私の OIDC Core 1.0 仕様に対する理解が浅いせいで、id_token_hint に対する私の解釈が不適切である可能性があります。そのため、上記の理由はあまり積極的に説明してきませんでした。しかし、つい先月も顧客から問い合わせを受けたので、説明文を残しておこうと思いました。