Skip to content

MS_OpenIDConnect

nishi_74322014 edited this page Sep 1, 2026 · 2 revisions

OpenID Connect

概要

Final を参照して記述。

  • OpenID Connect の用途としては、「認証の仕様である」と言ってイイ。

  • しかし技術的には、「ID トークン発行のための仕様」と考えたほうがイイ。

  • JWT

    • この ID トークンと呼ばれるトークンJWT アサーションを
      使用している(JSON Serialization ではなく、Compact Serialization を用いる)。
    • 従って、JWT の生成(署名)・検証の仕組みについては、JWT を参照。
    • このページでは、OpenID Connect の認証用の JWT アサーションの
      トークン・プロファイル(オプション仕様)についてを説明する。

補足(一言でいうと): OpenID Connect(OIDC)は
OAuth 2.0 の上に、認証(誰がログインしたか)を載せた仕様」。

OAuth 2.0 が返すアクセス トークンは
「API を叩く権限」でしかなく、
誰のものか Client が確かめられない(=認証に使えない)。
そこで「Client 宛て(aud)に、署名付きで、
誰がいつどうやって認証されたかを書いた JWT
」を返すことにした。
それが ID トークンである。

特徴

モジュラーデザイン

ユースケースに対応するため、複数の仕様から成り立っており、
それらをモジュール的に組み合わせることで多様な環境をサポートできる。

プロトコル概要

ざっくり、リクエスト → 認証・認可 → ユーザ情報を取得。

+--------+                                   +--------+
|        |---------(1) AuthN Request-------->|        |
|        |  +--------+                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|   RP   |  |  User  |                       |   OP   |
|        |  +--------+                       |        |
|        |<--------(3) AuthN Response--------|        |
|        |---------(4) UserInfo Request----->|        |
|        |<--------(5) UserInfo Response-----|        |
+--------+                                   +--------+
Client(RP)                                 IdP/STS(OP)

OAuth 2.0 への認証拡張

OAuth 2.0 との違いは、認証拡張機能が追加実装された点にある。

  • OAuth 2.0 では

    • 認証機能(「認証 Endpoint からユーザー属性クレーム群を取得する」)の仕様が無かった。
    • このため、この部分の拡張仕様(認証 Endpoint)に方言があり、実装上問題だった
  • これに対し OpenID Connect では、

    • ユーザー属性クレーム群取得の Endpoint がユーザー情報エンドポイントに標準化された。
    • これによって「認可」だけでなく「認証」の仕様も標準化された。

仕様の柱

内容
フロー OAuth 2.0 に認証結果とプロフィールの受渡し機能を追加(Authorization Code / Implicit / Hybrid)
ID トークン 基本構造 / 取得方法(認証のシーケンス)/ ユーザー属性クレーム群
追加のエンドポイント ユーザー情報エンドポイント

フロー

フロー選択の指針

# Property Authorization Code Flow Implicit Flow Hybrid Flow
1 全てのトークンは Authorization Endpoint から返却される no yes no
2 全てのトークンは Token Endpoint から返却される yes no no
3 トークンが User Agent に渡らない yes no no
4 Client 認証が可能である yes no yes
5 Refresh Token を利用できる yes no yes
6 通信が 1 往復だけである no yes no

補足(最新化:使うのは Authorization Code だけ): この表は
3 つのフローを対等に並べているが、現在の結論は明確である。

フロー 現在
Authorization Code(+ PKCE これ一択
Implicit 非推奨(RFC 9700 / OAuth 2.1
Hybrid 非推奨寄り。OpenID Connect Core の後継仕様でも整理対象

上表の「3. トークンが User Agent に渡らない」が yes なのは
Authorization Code だけであり、そこが決め手になった。

なお response_type=code id_token(Hybrid)は
FAPI 1.0 Advanced で要求されていたが、
FAPI 2.0 では code + PAR + PKCE に整理されている。

response_type 値とフローの対応

# response_type Flow
1 code Authorization Code Flow
2 id_token Implicit Flow
3 id_token token Implicit Flow
4 code id_token Hybrid Flow
5 code token Hybrid Flow
6 code id_token token Hybrid Flow

リクエスト・パラメタの追加・変更

  • OPTIONAL → REQUIRED

    • redirect_uri
    • scopeopenid を含まねばならない (MUST)
      openid scope 値が存在しない場合の挙動は定義しない。他の scope 値が存在してもよい。
  • response_type — 追加のパラメタ値がある(上表)。

  • nonce

    • Authorization Code Flow では OPTIONAL
    • Implicit Flow / Hybrid Flow では REQUIRED
  • claims 系

    • claims (OPTIONAL) — scope パラメタの詳細版
    • claims_locales (OPTIONAL) — クレームの多言語化対応
  • Request オブジェクト (OPTIONAL)

    • request — Request オブジェクト(JWT
    • request_uri — Request オブジェクトを返すエンドポイントの URL(https)
  • その他

パラメタ 内容
response_mode 応答モード(form_post など)
max_age 最大認証期間。ID トークンに auth_time クレームが必要になる
display 同意 UI の表示形式(page(既定)/ popup / touch / wap
prompt 再認証 / 認可の同意(none / login / consent / select_account
id_token_hint prompt=none の時に使う
login_hint 複数アカウント前提の際に、識別子のヒントとして利用する
ui_locales UI の表示言語
acr_values 認証コンテキスト クラス

補足(noncestate は別物): 混同されやすいので整理する。

パラメタ 目的 検証する場所
state CSRF 対策(このコールバックは自分が始めたものか) コールバック受信時
nonce ID トークンのリプレイ対策(このトークンは自分の要求への応答か) ID トークンの nonce クレーム
PKCE 認可コード横取り・注入対策 トークン交換時

3 つとも目的が違うため、いずれも省略できない

レスポンス・パラメタの追加・変更

  • Token Endpoint
    • id_tokenresponse_type で要求した場合に追加される。
    • token_typeBearer もしくは交渉した他の値。

TLS要件・その他

  • Authorization Endpoint / Token Endpoint との通信は TLS を用いなければならない (MUST)
  • Token Response に Cache-Control: no-store を指定 (MUST)。

Authorization Code Flow

  • scope="… openid …" / response_type="code"

OAuth 2.0 からのステップ上の拡張部分は無い。ただし、

  • クライアントは ID トークンを使用して、ユーザー属性クレーム群を取得して検証でき、
  • アクセス先が Resource Server の Endpoint がユーザー情報エンドポイントに
    特定されており、ここから、認証されたユーザとしてユーザー属性クレーム群を取得できる。

ステップ(太字OAuth 2.0 からの変更・拡張部分):

  1. Client prepares an Authentication Request containing the desired request parameters.
  2. Client sends the request to the Authorization Server.
  3. Authorization Server Authenticates the End-User.
  4. Authorization Server obtains End-User Consent/Authorization.
  5. Authorization Server sends the End-User back to the Client with an Authorization Code.
  6. Client requests a response using the Authorization Code at the Token Endpoint.
  7. Client receives a response that contains an ID Token and Access Token in the response body.
  8. Client validates the ID token and retrieves the End-User's Subject Identifier.

Implicit Flow

  • scope="… openid …" / response_type="id_token" または "id_token token"

  • ポイント — Authorization Endpoint から返される ID トークンに対して以下が必要になる。

    • nonce
    • at_hash"id_token token" の場合)

Hybrid Flow

  • response_type="code token" / "code id_token" / "code id_token token"
  • ID トークンと同時に、アクセストークンや認可コードが一緒に発行される。
    • 前段が Authorization Code Flow、中段が Implicit Flow に近いフロー、
      後段は Hybrid Flow の独自のフローになる。

主要な仕様

sub クレームの種類(Subject Identifier Types)

  • 「5.7. Claim Stability and Uniqueness」で言われているように、

    • 通常、sub クレーム値は、iss 内で一意
    • 故に、エンドユーザにとっては、isssub で一意
  • 故に、「8. Subject Identifier Types」では、

    • pairwise というオプションで、
    • Client 毎に sub クレーム値を変えることにより、
    • Client を跨った名寄せを困難にしてプライバシーを保護する
種類 内容
public 全ての Client に対し同一の sub クレーム値を提供する(既定値)
pairwise 各々の Client に対し異なる sub クレーム値を提供する
  • pairwise の要件

    • sub クレーム値が、OP 以外の Party にとって、可逆であってはならない (MUST NOT)
    • 異なる Sector Identifier 値は、異なる Subject Identifier 値にならなければならない (MUST)。
    • 同じ入力に対して必ず同じ sub クレーム値となる決定的アルゴリズムでなければならない (MUST)。
  • 計算例

    • sub = SHA-256(sector_identifier || local_account_id || salt)
    • sub = AES-128(sector_identifier || local_account_id || salt)
  • 注釈

    • sector_identifier : redirect_uri のホスト部を使用してもイイ
    • salt : IdP によって秘密にされている値

補足(RP 実装の鉄則): subiss 内でのみ一意なので、
ユーザーの主キーは iss + sub の組にすること。
sub 単独で突き合わせると、複数の IdP を許した瞬間に衝突しうる。

また、email を主キーにしてはならない
メールは変わるうえ、email_verifiedfalse の場合、
攻撃者が他人のメールを名乗れる
ASP.NET Identityの外部ログインを参照)。

pairwisePPID と同じ発想である。

ID トークン / 暗号関連 / ユーザー属性

補足(ID トークンの検証項目): RP が必ず検証すべき項目。

項目 内容
署名 jwks_uri の公開鍵で検証。alg はサーバー側で固定(JWS
iss 期待する OP と完全一致
aud 自分の client_id が含まれること
azp aud が複数のとき、自分であること
exp / iat 有効期間内(時刻ずれの許容は数分)
nonce 自分が送った値と一致
at_hash / c_hash Implicit / Hybrid で必要
acr / amr 要求した認証強度を満たすか(Authentication Context

その他の仕様

考慮点

IdP/STS(OP)の実装

  • 必須の実装 — 認可エンドポイント / Token エンドポイント /
    ユーザー情報エンドポイント / jwks_uri
  • Client(RP)次第の実装
  • Discovery、Dynamic Client Registration

補足: RP 実装では、エンドポイントを直書きせず
/.well-known/openid-configuration(Discovery)から解決するのが定石。
OP 側の URL 変更や鍵ローテーションに自動で追従できる
JWKを参照)。

セキュリティ

シーケンスとサンプル

  • OpenID Connect のシーケンス
    • Web アプリ(Basic Client Profile)
    • モバイルアプリ(Implicit Client Profile)
  • OpenID Connect のサンプル — Microsoft.Owin.Security.OpenIdConnect
    (現在は Microsoft.AspNetCore.Authentication.OpenIdConnect
    ASP.NET Core における 認証を参照)

参考


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

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally