サブジェクトとは
サブジェクトは、コードやトークンの発行対象となるエンドユーザー (リソースオーナー) の識別子です。サブジェクトの値は認可サーバーが生成し、subject リクエストパラメーターとして Authlete API に渡します。
まず、認可サーバーはユーザー認証後にサブジェクトを Authlete に渡し、Authlete は受け取ったサブジェクトを発行するコードやトークンに紐付けます (図 1)。
図 1: ユーザー認証後にサブジェクトを紐付ける例
図 2: トークンに含めてサブジェクトを返却する例
図 3: トークンの解析結果としてサブジェクトを返却する例
OAuth/OIDC 仕様との関係
Authlete のサブジェクトは、OAuth/OIDC 仕様の以下の要素のsub に相当します。
OpenID Connect Core 1.0, Section 5.7 は、クライアントがエンドユーザーの安定した識別子として依拠できるのは
sub と iss の組み合わせだけであり、email、phone_number、preferred_username を一意な識別子として使ってはならないとしています。sub は再割り当てされないため、クライアントは自身が管理するユーザーアカウントに sub を対応付けて保存し、以降のログインで同じユーザーを識別できます。
認可サーバーは、この性質を満たすエンドユーザーの識別子を生成し、Authlete に subject リクエストパラメーターでこの識別子を渡します。受け取った値を、Authlete は前述の各要素の sub として出力します。
責務の分担
サブジェクトに関する認可サーバーと Authlete の分担は次のとおりです。認可サーバー
- エンドユーザーが誰であるかを確定します。 このステップに Authlete は関与しません。認可サーバー自身がユーザーを認証する (ログインフォーム、パスキーなど) ほか、既存のセッションに依拠する、フェデレーションにより外部の ID プロバイダーの認証結果を受け入れる、といった方法があります。
- そのユーザーを表すサブジェクトを決定します。 上記の性質を満たす値、すなわち内部のアカウント ID のような、変更も再利用もされないものを使ってください。メールアドレスや表示名は変更されることがあるため適しません。外部の ID プロバイダーに認証を委ねる場合も、プロバイダーの識別子をそのまま渡すのではなく、認可サーバー自身のアカウント識別子に対応付けてください。プロバイダーの識別子はそのプロバイダー内で一意かつ安定であっても、認可サーバーの発行者内でそうとは限りません。
- 発行系 API (例: Issue Authorization Response) にサブジェクトを渡します。 なお、ID トークンや UserInfo レスポンスに含めるべきユーザーのその他の情報は、クレームとして渡します。Authlete はユーザーストアを持たず、サブジェクトから何かを導出することはありません。
Authlete
-
サブジェクトの形式をチェックします。 Authlete 3.0 の Issue Authorization Response が検査する要件は次のとおりです (他の発行系 API も同じ長さの上限を適用します)。
- 発行する認可コードやトークンにサブジェクトを紐付けます。
-
トークンや API レスポンスにサブジェクトを含めて返却します。 ID トークンの
subクレーム、UserInfo レスポンスのsub、JWT アクセストークンのsub、標準イントロスペクションレスポンスのsubメンバー、および Authlete 独自のイントロスペクション API のsubjectフィールドとして出力します (以降のセクションを参照)。
サブジェクトの流通経路
認可サーバーからの送信
認可サーバーは、エンドユーザーを特定したあと、サブジェクトを含むリクエストを発行系 (フロー完了) API に送信します。Authlete からの受信
Authlete に渡したサブジェクトは、発行されるトークンやレスポンスの次の場所に現れます。- アクセストークンにはサブジェクトが紐付けられ、トークンイントロスペクションの結果や、JWT アクセストークンが内包する値として出力されます。
- イントロスペクション: Process Introspection Request は
subjectとして、Process OAuth 2.0 Introspection Request は RFC 7662 のsubメンバーとして返すため、リソースサーバーは受け取ったトークンが誰のものかを判別できます。 - JWT アクセストークン:
subとして持ちます。Authlete の JWT アクセストークンは RFC 9068 のクレーム名を使いますが、同プロファイルには準拠していません。詳細は「JWTs in OAuth and OpenID Connect」の JWT Access Token の節を参照してください。 - クライアントクレデンシャルズグラントで発行されたトークンにはサブジェクトがなく、標準イントロスペクションでは
subが省略され、JWT アクセストークンでは"sub": nullになります。
- イントロスペクション: Process Introspection Request は
- ID トークンの
subクレームにはサブジェクトの値が入ります。- なお、Issue Authorization Response、Complete Device Authorization、Complete Backchannel Authentication へのリクエストに
subパラメーターを用いるとサブジェクト以外の値を指定できます (ただし、アクセストークンはサブジェクトに紐付いたまま)。これにより、実際のサブジェクトの値をクライアントアプリケーションから隠すことができます。詳細は ID トークンへのクレームの追加を参照してください。
- なお、Issue Authorization Response、Complete Device Authorization、Complete Backchannel Authentication へのリクエストに
- UserInfo レスポンスも、ID トークンと同様、
subクレームにはサブジェクトの値が入ります。- なお同じく、Issue UserInfo Response の
subパラメーターを用いるとサブジェクト以外の値を指定できます。
- なお同じく、Issue UserInfo Response の
サブジェクトを使ったトークンの操作
トークンにサブジェクトが紐付いたあとは、次の API や設定で、サブジェクトを使ってそのエンドユーザーのトークンを扱えます。- Process Introspection Request では
subjectをオプションのパラメーターとして指定できます。指定した場合、その値がアクセストークンに紐付くサブジェクトと一致しなければ、Authlete はaction=FORBIDDENを返すため、リソースサーバーはトークンが特定のユーザーのものであることを要求できます。 - List Issued Tokens は発行済みトークンをサブジェクトで絞り込めます。
- アクセストークンの単一化は、サブジェクトごとに最新のアクセストークンだけを有効に保ちます。
pairwise サブジェクト識別子の処理
pairwise サブジェクト識別子とは
OpenID Connect Core はsub クレームについて 2 種類のサブジェクト識別子タイプを定義しています。
仕様では、pairwise サブジェクト識別子の導出方法は定めていません。ただし、セクター識別子ごとに一意な
sub を算出すること、およびプロバイダー以外の誰にも逆算できないことを求めています (Section 8.1)。
Authlete の動作
認可サーバーから、その認可サーバー内で一意な識別子を受け取った Authlete は、次の手順で、クライアントごとのsub の値を導出します。
サブジェクト識別子タイプが
pairwise のクライアント、かつ sub パラメーターが指定されていないことが前提です。- クライアントのセクター識別子を決めます。
sector_identifier_uriが登録されていればそのホスト、なければ全リダイレクト URI に共通するホストです。sector_identifier_uriがなく、リダイレクト URI のホストもひとつに定まらない場合は、セクター識別子を導出できないため、Authlete はサブジェクトをそのままsubに使います。 subの値を決定します。 セクター識別子、サービス、サブジェクトなどからハッシュを計算し、URL セーフな Base64 (パディングなし、43 文字) でエンコードした文字列をsubとします。つまり、同じユーザーは同じクライアント (および同じセクターの他のクライアント) で常に同じsubを得る一方、異なるクライアントや異なるサービスでは異なる値になります。
sub です。一方、アクセストークンには認可サーバーが渡したサブジェクトがそのまま紐付くため、イントロスペクションの subject や JWT アクセストークンの sub にはその値が返ります。
pairwise サブジェクト識別子は Authlete 2.2 以降でサポートされています。
設定
サブジェクト識別子タイプはクライアント単位で設定します。クライアント設定の「サブジェクトタイプ」(subjectType、PUBLIC または PAIRWISE) で選びます。pairwise のクライアントでリダイレクト URI のホストが複数ある場合は、あわせて「セクター識別子 URI」(sectorIdentifierUri) を登録してください。登録がないと Authlete はセクター識別子を導出できず、public と同じ動作になります。