はじめに
認可リクエストの response_type パラメータ (RFC 6749, Section 3.1.1. Response Type) が正しくないと判断したとき、Authlete を用いる認可サーバの実装は、そのエラーをリダイレクトエンドポイント (RFC 6749, Section 3.1.2. Redirection Endpoint) に通知しません。かわりに、ユーザエージェントに 400 Bad Request を返します。
「response_type パラメータが指定されていなかったり、その値が未知であったりする場合も、リダイレクトでエラーを通知してほしい」、具体的には「response_type パラメータに関するエラーが検知されたとき、Authlete の /auth/authorization API レスポンス内の action パラメータの値を BAD_REQUEST ではなく LOCATION にしてほしい」という依頼を受けることがあります。しかし、このような動作になっているのには理由があるため、Authlete の実装を変更することはありません。
その理由を Authlete 社の Knowledge Base に記載してもよいのですが、この話題は Authlete に限らず、どの認可サーバの実装にも共通するものだと思いますので、ここで情報を共有したいと思います。
response_type に関するエラーをリダイレクトで通知しない理由
リダイレクト URI へのリダイレクトは、リダイレクト URI の検証が終わってからでなければなりません。リダイレクト URI に何も考えずにリダイレクトすると、セキュリティ問題が発生しうるからです。
リダイレクト URI の検証の際、response_type の情報が一部で利用されます。例えば OpenID Connect Dynamic Client Registration 1.0 の 2. Client Metadata では application_type は次のように定義されています。
OPTIONAL. Kind of the application. The default, if omitted, is
web. The defined values arenativeorweb. Web Clients using the OAuth Implicit Grant Type MUST only register URLs using the https scheme asredirect_uris; they MUST NOT uselocalhostas the hostname. Native Clients MUST only registerredirect_urisusing custom URI schemes or loopback URLs using thehttpscheme; loopback URLs uselocalhostor the IP loopback literals127.0.0.1or[::1]as the hostname. Authorization Servers MAY place additional constraints on Native Clients. Authorization Servers MAY reject Redirection URI values using thehttpscheme, other than the loopback case for Native Clients. The Authorization Server MUST verify that all the registeredredirect_urisconform to these constraints. This prevents sharing a Client ID across different types of Clients.
この文は、アプリケーションタイプが web のクライアントが Implicit フローを使う場合 (response_type に token または id_token が含まれる場合) にリダイレクト URI に対する追加検証が要求される、と解釈されるべきものと思われ、実際 Authlete はそのように実装しています。
また、RFC 6749 の 3.1.2.2. Registration Requirements には次のように書かれています。
The authorization server MUST require the following clients to register their redirection endpoint:
o Public clients.
o Confidential clients utilizing the implicit grant type.
この文は、コンフィデンシャルクライアントが Implicit フローを使う場合 (response_type に token または id_token が含まれる場合)、そのクライアントが必ず一つ以上のリダイレクト URI を登録済みであることを確認する、と解釈されるべきであると思われ、実際 Authlete はそのように実装しています。
上記の仕様に従うためには、リダイレクト URI の検証を始める前に response_type の検証を終えている必要があります。このため、もしも response_type の検証で「問題あり」と判定されると、リダイレクト URI の検証が終わっていないことになりますから、リダイレクトできません (セキュリティ上の理由によりリダイレクトすべきではありません)。
RFC 6749 は、リダイレクト URI の検証が完了する前にエラーが発生した場合のエラー報告はどうあるべきか、について定義していません。そのため、この部分は実装依存です。Authlete を用いる認可サーバの実装は、エラーの内容を JSON で記述し、400 Bad Request を返します。
Authlete の実装は、できる限りリダイレクトしようとします。一方、世の中にはエラーの場合はほとんどリダイレクトせず、かわりにエラーを示す HTML を返すものがあります。例えば Google の実装はそのようになっており、彼らの実装がエラーでリダイレクトするのは、かなり限定的なケースです。
Authlete はできるだけ早くリダイレクト URI の検証を済ませようとしますが、それでも、その検証に先立って次の項目が検証されます。これらの検証中に発生したエラーは、リダイレクトエンドポイントには報告されません。
-
client_id(クライアント識別子; OpenID Federation もしくは CIMD の自動クライアント登録処理という重い処理が走る可能性もある) -
request,request_uri(リクエストオブジェクトの処理。JAR や PAR、FAPI の各種設定に影響を受け、Authlete の実装内でもかなり複雑な処理。) -
trust_chain(OpenID Federation で登録されたクライアントメタデータを必要に応じて更新) - CIMD (CIMD で登録されたクライアントメタデータを必要に応じて更新)
-
response_type(まずはresponse_typeパラメータの処理) -
prompt(値としてnoneが設定されていると特別対応が必要なので早めに検証) -
scope(openidやoffline_accessなど、検証に影響するスコープがある) -
response_type(改めてresponse_typeの検証) -
response_type(FAPI のための追加検証) redirect_uri(ここまで準備できて初めてリダイレクト URI の検証に取り掛かれる)
リクエストオブジェクトの中に response_type が入っている可能性があるので、リクエストオブジェクトの処理 (request パラメータと request_uri パラメータの処理) を response_type パラメータの処理よりも先に実行しなければなりません。
また、response_types や redirect_uris といったクライアントメタデータを response_type や redirect_uri の検証処理中に参照するので、OpenID Federation や CIMD によるクライアントメタデータ自動更新処理を response_type パラメータの処理よりも先に実行しなければなりません。
RFC 6749 の Section 3.1.1. Response Type に次のような記載があります。
If an authorization request is missing the
"response_type"parameter, or if the response type is not understood, the authorization server MUST return an error response as described in Section 4.1.2.1.
この記述は、response_type の検証が通らなければ Section 4.1.2.1 の方法でエラー応答を返すことを要求するものです。
その Section 4.1.2.1. Error Response は次のように述べています。
If the request fails due to a missing, invalid, or mismatching redirection URI, or if the client identifier is missing or invalid, the authorization server SHOULD inform the resource owner of the error and MUST NOT automatically redirect the user-agent to the invalid redirection URI.
If the resource owner denies the access request or if the request fails for reasons other than a missing or invalid redirection URI, the authorization server informs the client by adding the following parameters to the query component of the redirection URI using the "application/x-www-form-urlencoded" format, per Appendix B:
つまり、リダイレクト URI の検証が終わっていなければリダイレクトしてはならない、という要求事項です。
Authlete のように、リダイレクト URI の検証の前に response_type のチェックをおこなっている認可サーバの実装は、response_type で問題が発生すると、そのエラーをリダイレクトでは報告しません。
unsupported_response_type エラーは通知しない
RFC 6749 で unsupported_response_type というエラーコードが定義されているのは知っていますが、このエラーコードを含む通知をリダイレクトエンドポイントに Authlete が通知することはありません。
参考情報
動画
2020 年 5 月 27 日にオンライン開催した『OAuth & OIDC 勉強会【認可リクエスト編】』でリダイレクト処理について説明しているので、是非ご視聴ください。
記事
おわりに
世界の金融業界で使われる品質の認可サーバを実装しようとすると、response_type パラメータの処理でさえ、RFC 6749 以外の標準仕様書も参照しながら実装しなければなりません。ぱっと思いつくだけでも、次の仕様群が response_type の処理に影響します。
- RFC 6749: The OAuth 2.0 Authorization Framework
- RFC 7591: OAuth 2.0 Dynamic Client Registration Protocol
- RFC 7592: OAuth 2.0 Dynamic Client Registration Management Protocol
- RFC 9101: The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)
- RFC 9126: OAuth 2.0 Pushed Authorization Requests
- OpenID Connect Core 1.0
- OpenID Connect Dynamic Client Registration 1.0
- OAuth 2.0 Multiple Response Type Encoding Practices
特に、OpenID Connect Core 1.0 内のリクエストオブジェクトに関する仕様を RFC 9101 に切り出した際に加えられた破壊的変更 (後方互換性のない変更) が、response_type の処理方法にも影響を与えることには注意が必要です。詳細は別記事『JAR (JWT-Secured Authorization Request) に関する実装者の覚書』にまとめてあります。
「response_type だけでも、いざ実装しようと思ったらこんなに考えるべきことがあるのか。商用品質の認可サーバを書くのはしんどい」と思った方、是非 Authlete の利用をご検討ください!