MS_OIDCIDToken - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki

OpenID Connect - IDトークン

概要

Final を参照して記述。

  • OpenID ConnectOAuth 2.0 を拡張した
    主要なクレーム(クレームセット)を格納するアサーション
  • 仕様全体を通してメッセージ形式に JWT(アサーション)を採用。
  • 以下のクレームの値を含むクレームセット。
    • 発行元の IdP(OP)識別子
    • 発行先の RP 識別子(client_id
    • ユーザー識別子
    • 発行日時
  • クレームの扱いについて外部クレーム機能を定義している(集約 / 分散)。

補足(ID トークンとアクセス トークンは役割が違う): 最も混同されやすい点。

ID トークン アクセス トークン
目的 認証(誰か) 認可(何ができるか)
宛先 (aud) Client 自身 Resource Server
中身 Client が読むもの Client にとっては不透明
使い方 Client が検証して終わり API に添えて送る

ID トークンを API に送ってはならないaud が違う)。
逆に アクセス トークンからユーザーを判定してはならない
(中身の解釈は保証されない)。
この誤用は実装で頻出する。

詳細

クレームセット

必須クレーム群

クレーム 内容
iss (issuer) Authorization Server の識別子。URI 形式が推奨(Discovery のため)
sub (subject) ユーザーテーブルのプライマリーキーやそれに準ずるもの
aud (audience) client_id の値を含む。複数要素の配列を含んでも良い (MAY)
exp (expiration time) JWT の有効期限(Unix エポックからの経過
iat (issued at) JWT の発行日時(同上)

補足(subiss とセットで一意): sub
その IdP の中でのみ一意である。
複数の IdP を扱う場合、sub だけでユーザーを識別してはならない
(別 IdP の別人と衝突しうる)。iss + sub の組で管理する。

また、subメールアドレスを使ってはならない
メールは変更されうるため、恒久的な識別子として不適切である。

ケースバイケースなクレーム群

クレーム 内容
auth_time ユーザー認証時刻。リクエスト パラメタやメタ情報設定次第で必須
nonce リプレイアタック防止。発行依頼に付属する nonce 値をそのまま埋め込む。Implicit / Hybrid では必須

オプションのクレーム群

クレーム 内容
acr 認証コンテキストのクラス
amr 認証手法を示す(pwd / otp / mfa など)
azp 特に aud が複数要素の配列の場合、認可された対象者を明示する

補足(acr / amr は多要素認証の検証に使う): 「本当に多要素で
認証されたか」を Client が確認する手段である。

{ "acr": "urn:mace:incommon:iap:silver", "amr": ["pwd", "otp"] }

FAPI Part 2が「LoA 3(2 要素以上)」を要求する際、
Client 側はこれらのクレームで実際の認証強度を検証する。
高い保証レベルを要求するだけでなく、
満たされたことを確認するところまでが実装になる。

Hashクレーム

トークン置換攻撃を検知可能。

Authorization Endpoint から ID トークンを返す場合(Implicit / Hybrid)に必要になる。

クレーム 対象 必須になる条件
at_hash Access Token のハッシュ値 response_typeid_tokentoken が含まれる時
c_hash Code のハッシュ値 response_typecodeid_token が含まれる時

計算方法(共通):

  1. ID Token の JOSE Header の alg で使用されるハッシュアルゴリズムを用いる
  2. 対象の ASCII オクテット列からハッシュ値を求める
  3. 左半分を base64url エンコードする

補足(s_hash は FAPI の追加): FAPI Part 2
これに s_hashstate のハッシュ) を追加する。
標準の OIDC には無いクレームである。

クレーム 守る対象 定義元
at_hash access_token OIDC Core
c_hash code OIDC Core
s_hash state FAPI

state まで守ることで、認可レスポンス全体の改ざんを検知できる。

外部クレーム

IdP(OP)は、扱うクレームの内容によってどちらを利用すべきか判断する。

種類 内容 向く場面
集約クレーム(Aggregated) 別の IdP が持つクレームを署名付きで同梱する 一定期間変更されないもの(キャッシュが効く)
分散クレーム(Distributed) クレームそのものではなく、問い合わせ先の URL(+ アクセストークン)を渡す 頻繁に更新されるもの

検証処理

Client は、ID トークンを検証する。

基本的な検証処理

  1. JWS署名の検証 / JWE暗号の復号
    • Client は Issuer から提供された鍵を利用しなければならない (MUST)。
    • alg の値は、デフォルトの RS256
      もしくは Registration による id_token_signed_response_alg パラメタ値
  2. iss クレームの検証(Discovery で取得した Issuer 値に一致)
  3. aud / azp クレームの検証
    • aud に自身の client_id が含まれることを確認する。
    • aud が複数要素の配列の場合、azp に含まれることを確認すべき。
  4. 時刻
    • exp(現在時刻より後)
    • iat(Client から見て古過ぎない、nonce 保存期間を制限)
    • auth_timemax_age を使用してチェックし再認証を要求)
  5. acr の検証(適切かどうかをチェック。値と意味は仕様の対象外)

補足(検証を省くと何が起きるか): 各項目を省いた場合の帰結。

省いた検証 起きること
署名 偽造トークンで誰にでもなりすませる
alg の固定 alg: none / アルゴリズム混同攻撃(JWAを参照)
iss 別の IdP が発行したトークンを受け入れてしまう
aud 他サービス向けのトークンを流用される(トークン転用)
exp 期限切れトークンが永久に使える
nonce リプレイ攻撃

ライブラリに任せる場合も、
**「issaud を明示的に指定しているか」**は必ず確認したい。
既定で検証されない実装がある。

フロー毎の差異

フロー 検証の要点
Authorization Code Flow JWS 検証 / JWE 復号。Token Endpoint との直接通信で受け取った場合、署名確認の代わりに TLS で issuer を確認してもよい (MAY)
Implicit Flow JWS 署名の検証のみ(JWE 復号は不可)。nonceat_hashREQUIRED
Hybrid Flow Authorization Endpoint 側は JWS のみ + c_hash / at_hash。Token Endpoint 側は JWS/JWE + at_hash

Google

Google で OpenID Connect の認証で取得したクレームセット。

{
  "iss": "accounts.google.com",
  "at_hash": "・・・",
  "email_verified": "true",
  "sub": "ユーザーの一意識別子",
  "azp": "認可された対象者のID.apps.googleusercontent.com",
  "email": "・・・・",
  "aud": "クライアント識別子.apps.googleusercontent.com",
  "iat": 1234567890,
  "exp": 1234571490
}

補足(email_verified が文字列になっている): 上の例では
"email_verified": "true"文字列で入っているが、
仕様上は boolean である。
実装によって型が揺れることがあるため、
パース時に型を決め打ちしない方が安全である。

また、email をユーザー識別子に使ってはならない
(変更されうる、email_verifiedfalse のことがある)。
識別は iss + sub で行う。

参考


Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth

⚠️ **GitHub.com Fallback** ⚠️