メインコンテンツまでスキップ

OpenID Connect Core 1.0

OpenID Connect(OIDC)は、OAuth 2.0 に Identity レイヤーを追加した ID 連携プロトコルです。このドキュメントでは、OIDC Core の仕組みを解説します。


第1部: 概要編

OpenID Connect とは何か?

OpenID Connect は、IdP(Identity Provider)が認証したユーザーの情報を RP(Relying Party)に提供するための ID 連携(Identity Federation)プロトコルです。

┌────────────┐                                      ┌────────────┐
│ RP │ │ IdP │
│ (Webアプリ) │ │ (認証基盤) │
└─────┬──────┘ └──────┬─────┘
│ │
│ 「このユーザーは誰?」 │
│ ──────────────────────────────────────────────────►│
│ │
│ IdP がユーザーを認証
│ │
│ ID Token(認証結果 + ユーザー情報) │
│ ◄──────────────────────────────────────────────────│
│ │
│ RP は受け取った情報を使って │
│ ・新規ユーザー登録(身元確認) │
│ ・既存ユーザーのログイン(当人認証) │
│ を行う │

重要: 「OIDC は認証」という説明は不正確。認証を行うのは IdP であり、OIDC は IdP が認証した結果を RP に伝えるためのプロトコル。

OAuth 2.0 と OIDC の関係

OAuth 2.0OpenID Connect
認可のためのフレームワークOAuth 2.0 + Identity レイヤー
「何にアクセスできるか」を扱う「誰であるか」を扱う
アクセストークンを発行ID トークンを追加で発行
ユーザー情報の形式は未定義ユーザー情報の形式を標準化

OIDC の主要コンポーネント

コンポーネント説明
ID Tokenユーザーの認証情報を含む署名付き JWT
UserInfo Endpointユーザーの属性情報を取得する API
標準クレームユーザー情報の標準的な表現方法
認証コンテキストいつ・どのように認証されたかの情報

第2部: 詳細編

3 つの認証フロー

OIDC は OAuth 2.0 のフローを拡張し、3 つの認証フローを定義。

フローresponse_type用途
Authorization Code Flowcodeサーバーサイドアプリ(推奨)
Implicit Flowid_token / id_token tokenSPA(非推奨)
Hybrid Flowcode id_token など特殊なユースケース

Authorization Code Flow

最も一般的で安全なフロー。

┌────────┐          ┌────────┐          ┌────────┐
│ User │ │ RP │ │ IdP │
└───┬────┘ └───┬────┘ └───┬────┘
│ │ │
│ (1) ログイン要求 │ │
│ ─────────────────►│ │
│ │ │
│ (2) 認可リクエスト │ │
│ ◄─────────────────│ │
│ │ │
│ (3) IdP にリダイレクト │
│ ──────────────────────────────────────►│
│ │ │
│ (4) ユーザー認証 + 同意 │
│ ◄────────────────────────────────────►│
│ │ │
│ (5) 認可コード │ │
│ ◄──────────────────────────────────────│
│ ─────────────────►│ │
│ │ │
│ │ (6) トークンリクエスト
│ │ ─────────────────►│
│ │ │
│ │ (7) ID Token + Access Token
│ │ ◄─────────────────│
│ │ │
│ (8) ログイン完了 │ │
│ ◄─────────────────│ │

認可リクエスト

GET /authorize?
response_type=code
&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcallback
&scope=openid%20profile%20email
&state=af0ifjsldkj
&nonce=n-0S6_WzA2Mj
HTTP/1.1
Host: idp.example.com
パラメータ必須説明
response_typecode(Authorization Code Flow)
client_idクライアント識別子
redirect_uriコールバック URL
scopeopenid を含むことが必須
state推奨CSRF 対策
nonce推奨リプレイ攻撃対策

scope の値

scope取得できる情報
openid必須。OIDC リクエストであることを示す
profilename, family_name, given_name, picture など
emailemail, email_verified
addressaddress
phonephone_number, phone_number_verified

ID Token

ID Token は、IdP がユーザーを認証したことを証明する署名付き JWT

{
"iss": "https://idp.example.com",
"sub": "24400320",
"aud": "s6BhdRkqt3",
"exp": 1704070800,
"iat": 1704067200,
"auth_time": 1704067180,
"nonce": "n-0S6_WzA2Mj",
"acr": "urn:mace:incommon:iap:silver",
"amr": ["pwd", "otp"],
"azp": "s6BhdRkqt3"
}

ID Token の必須クレーム

クレーム説明
issIdP の識別子(URL)
subユーザーの識別子(IdP 内で一意)
aud対象の RP(client_id)
exp有効期限
iat発行時刻

ID Token のオプションクレーム

クレーム説明
auth_timeユーザーが認証された時刻
nonceリクエスト時に送った nonce(一致確認必須)
acr認証コンテキストクラス(認証の強度)
amr認証方法(pwd, otp, fido など)
azp認可された当事者

ID Token の検証

RP は ID Token を受け取ったら、以下を検証する必要があります。

1. 署名検証
└── IdP の公開鍵(JWKS エンドポイントから取得)で検証

2. iss 検証
└── 期待する IdP の識別子と一致するか

3. aud 検証
└── 自分の client_id が含まれているか

4. exp 検証
└── 現在時刻 < exp(有効期限内か)

5. iat 検証
└── 発行時刻が許容範囲内か

6. nonce 検証(リクエスト時に送った場合)
└── リクエスト時の nonce と一致するか

7. acr 検証(要求した場合)
└── 要求した認証レベルを満たしているか

UserInfo Endpoint

ID Token に含まれない追加のユーザー情報を取得。

GET /userinfo HTTP/1.1
Host: idp.example.com
Authorization: Bearer SlAV32hkKG

レスポンス:

{
"sub": "24400320",
"name": "Jane Doe",
"given_name": "Jane",
"family_name": "Doe",
"email": "janedoe@example.com",
"email_verified": true,
"picture": "https://example.com/janedoe/photo.jpg"
}

標準クレーム

OIDC で定義されている標準的なユーザー属性。

クレーム説明
sub識別子"24400320"
nameフルネーム"Jane Doe"
given_name"Jane"
family_name"Doe"
emailメールアドレス"janedoe@example.com"
email_verifiedメール確認済みかtrue
phone_number電話番号"+1-555-555-5555"
address住所{"country": "JP", ...}
birthdate生年月日"1990-01-15"
pictureプロフィール画像 URL"https://..."

Discovery

IdP の設定情報を自動検出するための仕組み。

GET /.well-known/openid-configuration HTTP/1.1
Host: idp.example.com

レスポンス:

{
"issuer": "https://idp.example.com",
"authorization_endpoint": "https://idp.example.com/authorize",
"token_endpoint": "https://idp.example.com/token",
"userinfo_endpoint": "https://idp.example.com/userinfo",
"jwks_uri": "https://idp.example.com/.well-known/jwks.json",
"scopes_supported": ["openid", "profile", "email"],
"response_types_supported": ["code", "id_token", "token id_token"],
"subject_types_supported": ["public", "pairwise"],
"id_token_signing_alg_values_supported": ["RS256", "ES256"]
}

Subject Identifier Types

ユーザー識別子(sub)の生成方式。

タイプ説明
public全ての RP に同じ sub を返す
pairwiseRP ごとに異なる sub を返す(プライバシー保護)
Public:
RP-A: sub = "user-123"
RP-B: sub = "user-123" ← 同じ

Pairwise:
RP-A: sub = "abc123..." ← RP-A 用に生成
RP-B: sub = "xyz789..." ← RP-B 用に生成(異なる)

セキュリティ考慮事項

項目推奨事項
state必須。CSRF 対策
nonce必須。リプレイ攻撃対策
ID Token 検証すべてのクレームを検証
HTTPS必須
PKCE推奨(特にパブリッククライアント)

参考リンク