-
Notifications
You must be signed in to change notification settings - Fork 0
MS_OpenIDConnect
Final を参照して記述。
-
OpenID Connect の用途としては、「認証の仕様である」と言ってイイ。
-
しかし技術的には、「ID トークン発行のための仕様」と考えたほうがイイ。
補足(一言でいうと): 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 値 |
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-
scope—openidを含まねばならない (MUST)。
openidscope 値が存在しない場合の挙動は定義しない。他の 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 |
認証コンテキスト クラス値 |
補足(
nonceとstateは別物): 混同されやすいので整理する。
パラメタ 目的 検証する場所 stateCSRF 対策(このコールバックは自分が始めたものか) コールバック受信時 nonceID トークンのリプレイ対策(このトークンは自分の要求への応答か) ID トークンの nonceクレームPKCE 認可コード横取り・注入対策 トークン交換時 3 つとも目的が違うため、いずれも省略できない。
- Token Endpoint
-
id_token—response_typeで要求した場合に追加される。 -
token_type—Bearerもしくは交渉した他の値。
-
- Authorization Endpoint / Token Endpoint との通信は TLS を用いなければならない (MUST)。
- Token Response に
Cache-Control: no-storeを指定 (MUST)。
-
scope="… openid …"/response_type="code"
OAuth 2.0 からのステップ上の拡張部分は無い。ただし、
- クライアントは ID トークンを使用して、ユーザー属性クレーム群を取得して検証でき、
- アクセス先が Resource Server の Endpoint がユーザー情報エンドポイントに
特定されており、ここから、認証されたユーザとしてユーザー属性クレーム群を取得できる。
ステップ(太字が OAuth 2.0 からの変更・拡張部分):
- Client prepares an Authentication Request containing the desired request parameters.
- Client sends the request to the Authorization Server.
- Authorization Server Authenticates the End-User.
- Authorization Server obtains End-User Consent/Authorization.
- Authorization Server sends the End-User back to the Client with an Authorization Code.
- Client requests a response using the Authorization Code at the Token Endpoint.
- Client receives a response that contains an ID Token and Access Token in the response body.
- Client validates the ID token and retrieves the End-User's Subject Identifier.
-
scope="… openid …"/response_type="id_token"または"id_token token" -
ポイント — Authorization Endpoint から返される ID トークンに対して以下が必要になる。
nonce-
at_hash("id_token token"の場合)
-
response_type="code token"/"code id_token"/"code id_token token" - ID トークンと同時に、アクセストークンや認可コードが一緒に発行される。
- 前段が Authorization Code Flow、中段が Implicit Flow に近いフロー、
後段は Hybrid Flow の独自のフローになる。
- 前段が Authorization Code Flow、中段が Implicit Flow に近いフロー、
-
「5.7. Claim Stability and Uniqueness」で言われているように、
- 通常、
subクレーム値は、iss内で一意 - 故に、エンドユーザにとっては、
iss+subで一意
- 通常、
-
故に、「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 実装の鉄則):
subはiss内でのみ一意なので、
ユーザーの主キーはiss+subの組にすること。
sub単独で突き合わせると、複数の IdP を許した瞬間に衝突しうる。また、
メールは変わるうえ、email_verifiedがfalseの場合、
攻撃者が他人のメールを名乗れる
(ASP.NET Identityの外部ログインを参照)。
pairwiseは PPID と同じ発想である。
補足(ID トークンの検証項目): RP が必ず検証すべき項目。
項目 内容 署名 jwks_uriの公開鍵で検証。algはサーバー側で固定(JWS)iss期待する OP と完全一致 aud自分の client_idが含まれることazpaudが複数のとき、自分であることexp/iat有効期間内(時刻ずれの許容は数分) nonce自分が送った値と一致 at_hash/c_hashImplicit / Hybrid で必要 acr/amr要求した認証強度を満たすか(Authentication Context)
- 追加の応答タイプ(
response_type) - 追加の応答モード(
response_mode)(OAuth 2.0 Form Post Response Mode) - 認証コンテキスト クラス
- Request オブジェクト
- クライアント認証
- Self-Issued OP
- CIBA Flow(CIBA)
- Identity Assurance
- Offline Access / Session Management / ログイン開始エンドポイント
- 必須の実装 — 認可エンドポイント / Token エンドポイント /
ユーザー情報エンドポイント /jwks_uri - Client(RP)次第の実装
- Discovery、Dynamic Client Registration
補足: RP 実装では、エンドポイントを直書きせず
/.well-known/openid-configuration(Discovery)から解決するのが定石。
OP 側の URL 変更や鍵ローテーションに自動で追従できる
(JWKを参照)。
- OAuth 2.0 Threat Model and Security Considerations
- サーバ認証 / トークン / 暗号化 / Request オブジェクト
- OpenID Connect のシーケンス
- Web アプリ(Basic Client Profile)
- モバイルアプリ(Implicit Client Profile)
- OpenID Connect のサンプル —
Microsoft.Owin.Security.OpenIdConnect
(現在はMicrosoft.AspNetCore.Authentication.OpenIdConnect。
ASP.NET Core における 認証を参照)
- OpenID Connect Core 1.0
https://openid.net/specs/openid-connect-core-1_0.html - OpenID Foundation
https://openid.net/ - OpenID ファウンデーション・ジャパン(翻訳)
https://openid-foundation-japan.github.io/ - OpenID Connectユースケース、OAuth 2.0の違い・共通点まとめ - Build Insider
http://www.buildinsider.net/enterprise/openid/connect - OpenID Connect 全フロー解説 - Qiita(TakahikoKawasaki)
https://qiita.com/TakahikoKawasaki/items/4ee9b55db9f7ef352b47
Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。