「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次  †
概要  †
Finalを参照して記述。
- JWT
- このIDトークンと呼ばれるトークンはJWTアサーションを使用している。
(JSON Serializationではなく、Compact Serializationを用いる。) 
- 従って、JWTの生成(署名)・検証の仕組みについては、JWTを参照のこと。
 
- このページでは、OpenID Connectの認証用のJWTアサーションの
トークン・プロファイル(オプション仕様)についてを説明する。 
 
特徴  †
モジュラーデザイン  †
ユースケースに対応するため、
- 複数の仕様から成り立っており、
 
- それらをモジュール的に組み合わせることで
 
多様な環境をサポートできる。
プロトコル概要  †
ざっくり、リクエスト→認証・認可→ユーザ情報を取得。
+--------+                                   +--------+
|        |                                   |        |
|        |---------(1) AuthN Request-------->|        |
|        |                                   |        |
|        |  +--------+                       |        |
|        |  |        |                       |        |
|        |  |  End-  |<--(2) AuthN & AuthZ-->|        |
|        |  |  User  |                       |        |
|   RP   |  |        |                       |   OP   |
|        |  +--------+                       |        |
|        |                                   |        |
|        |<--------(3) AuthN Response--------|        |
|        |                                   |        |
|        |---------(4) UserInfo Request----->|        |
|        |                                   |        |
|        |<--------(5) UserInfo Response-----|        |
|        |                                   |        |
+--------+                                   +--------+
Client(RP)                                IdP/STS(OP)
OAuth 2.0との違いは、認証拡張機能が追加実装された点にある。
- OAuth 2.0では
- 認証機能(「認証Endpointからユーザー属性クレーム群を取得する」)の仕様が無かった。
 
- このため、この部分の拡張仕様(認証Endpoint)に方言があり、実装上問題だった。
 
 
- OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜
 
仕様の柱  †
OAuth 2.0に認証結果とプロフィールの受渡し機能を追加。
追加のエンドポイント  †
フロー  †
概要  †
フロー選択の指針  †
特定のコンテキストにおいてどのフローを選択すればよいかの指針
| # | 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 | 
| 7 | 殆どの通信がサーバ間通信である | yes | no | varies | 
 
response_type 値とフローの対応  †
メッセージのシリアライズ方法  †
- GETリクエスト:
application/x-www-form-urlencoded (Query String Serialization) 
- POSTリクエスト:
application/x-www-form-urlencoded (Form Serialization) 
- JSON
定義されていないが、以下で利用されるモノと思われる。 
- GET, POSTレスポンス:
Response body 
- GETリクエスト:
Query String Serialization 
- POSTリクエスト:
Form Serialization 
リクエスト・パラメタの追加・変更  †
- OPTIONAL ---> REQUIRED
- redirect_uri
 
- scope
scope="* openid *"は必須。
- OpenID Connect リクエストは scope に openid を含まねばならない (MUST).
 
- openid scope 値が存在しない場合の挙動は定義しない.
 
- 他の scope 値が存在していても良い (MAY).
 
 
 
- request
Requestオブジェクト(JWT) 
- request_uri
Requestオブジェクト(JWT)を返すエンドポイントのUrl(https) 
- display (OPTIONAL)
Authorization Server は認証/認可の同意 UI を、
- page
User Agent の全画面に表示すべき(既定値) 
- popup
User Agent のポップアップウィンドウに表示すべき. 
- touch
タッチ・インタフェースを持つデバイスに適した形で表示すべき. 
- wap
"feature phone"に適した形で表示すべき. 
 
- prompt (OPTIONAL)
再認証/認可の同意を要求するかどうか指定するスペース区切りの ASCII 文字列のリスト 
- none
再認証/認可の同意を要求(表示)してはならない. 
- login
再認証の同意を要求(表示)すべき. 
- consent
再認証/認可の同意を要求(表示)すべき. 
- select_account
複数アカウント前提の際に、アカウント選択を促すべき. 
- hint
基本、(素?)無視。
- id_token_hint (OPTIONAL)
prompt=noneの時に使う 
- login_hint (OPTIONAL)
複数アカウント前提の際に、識別子のヒントとして利用する。 
 
- その他
- ui_locales (OPTIONAL)
UI の表示言語および文字種スペース区切りの言語タグ値のリスト 
- acr_values (OPTIONAL)
認証コンテキスト クラス値 
 
レスポンス・パラメタの追加・変更  †
- Token Endpoint
- id_token
response_typeで要求した場合に追加される。 
- token_type
Bearer もしくは Client が Authorization Server と交渉した他の token_type の値と規定。 
 
TLS要件  †
以下との通信は、TLS を用いなければならない (MUST).
- Authorization Endpoint
 
- Token Endpoint
 
その他の追加要件  †
- Token Response に 以下の HTTP レスポンスヘッダーを指定(MUST).
| # | Header Name | Header Value | 
| 1 | Cache-Control | no-store | 
| 21 | Pragma | no-cache | 
 
Authorization Code Flow  †
概要  †
OAuth 2.0 からのステップ上の拡張部分は無い。
ただし、
ステップ  †
朱書きは、OAuth 2.0 からのステップ上の変更・拡張部分。
The Authorization Code Flow goes through the following steps.
- 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.
 
Implicit Flow  †
概要  †
ステップ  †
朱書きは、OAuth 2.0 からのステップ上の変更・拡張部分。
The Implicit Flow follows the following steps:
- 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 ID Token and, if requested, an Access Token.
 
- Client validates the ID token and retrieves the End-User's Subject Identifier.
 
ポイント  †
- IDトークンクレームの追加要件
Authorization Endpoint から返されるIDトークンに対して以下が必要になる。
 
Hybrid Flow  †
- response_type=
- "code token"
 
- "code id_token"
 
- "code id_token token"
 
 
概要  †
IDトークンと同時に、アクセストークンや認可コードが一緒に発行される。
- 中段:Implicit Flow
認可エンドポイントからRedirectエンドポイントへ、
Implicitなフラグメント部を使用したリダイレクトをするまで。 
- 後段:Hybrid Flow
UserAgent?側でフラグメント部のcode, id_token, tokenを取得、 
- codeをClientで利用する。
その後、UserAgent?がClientにcodeを送付し、
Client側でcodeを使用してアクセストークン・リクエストを行う。 
ステップ  †
朱書きは、Authorization Code Flowとの差異。
The Hybrid Flow follows the following steps:
- 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 and,
depending on the Response Type, one or more additional parameters. 
- 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.
 
ポイント  †
- codeをUserAgent?からClientに渡す方法
定義されていないが、クライアント側・サーバ側の違いはあるが、
双方ともClientなので、恐らく、POSTなどでcodeをUserAgent?からClientに渡せば良さそう。 
- codeとtokenのaccess_tokenの差異
セキュリティ特性によって以下が異なって良いと定義されている。
 
- IDトークンクレームの追加要件
- Authorization Endpoint から返されるIDトークンに対して以下が必要になる。
 
 
- Authorization Endpoint と Token Endpoint から返されるIDトークンのクレームについて以下が必要になる。
 
- issクレームと subクレームは同一でなければならない (MUST).
 
- 両方に同じ Authentication イベントに関する Claim を含めるべき(SHOULD).
 
- End-User に関するクレームは、
Authorization Endpoint ≦ Token Endpointから返すクレームとしてよい (MAY).
ただし、クレームが両方に存在する場合, その値は同値であるべき (SHOULD). 
主要な仕様  †
subクレームの種類  †
(Subject Identifier Types)
- 「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の値  †
pairwiseのsubクレーム値
- 要件
- subクレーム値が, OP(IdP/STS) 以外の 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 )
 
- GUID = ローカルアカウントID, Sector Identifier(変換テーブル)
 
 
ユーザー属性  †
追加の仕様  †
追加された仕様についてまとめる。
オプションの仕様  †
その他  †
Offline Access  †
offline_access scopeにより、
- Clientは、Resource Ownerの代わりに、長期間にわたってリソースにアクセスできる。
 
- このため、このパラメタは、Refresh Tokenの発行に関係する。
 
Session Management  †
ログイン開始エンドポイント  †
アプリXのログイン・フローが、サード・パーティーの
Client(RP)やIdP/STS(OP)によって開始される仕組み。
- 要するに、サード・パーティーのClient(RP)やIdP/STS(OP)から、
- リダイレクト(とは言え、GETとPOST要求を受入)で
 
- Client(RP)のログイン開始エンドポイントに遷移し、
 
- IdP/STS(OP)に認可リクエストを送信する。
 
- IdP/STS(OP)で認証後、Client(RP)のRedirectエンドポイントに遷移し、
 
- 更に、その後、指定されたランディング・ページに遷移する。
 
 
- iss (REQUIRED)
認可リクエストを送信するIdP/STS(OP)を示す 
- login_hint (OPTIONAL)
認可リクエストにlogin_hintパラメタ値として含める. 
- target_link_uri (OPTIONAL)
- Redirectエンドポイントから、指定されたランディング・ページに遷移。
 
- オープンリダイレクターとして使用されることを防ぐためtarget_link_uri値を検証する (MUST).
 
 
考慮点  †
IdP/STS(OP)の実装  †
必須の実装  †
- Locales
- ui_locales
 
- claims_locales
 
 
- Response Type
- id_token
 
- code (Self-Issued OP 以外)
 
- id_token token (Self-Issued OP 以外)
 
 
- UserInfo? Endpoint (Self-Issued OP 以外)
 
- JWK 公開(jwks_uri、X.509 形式でも可)
 
- Requestオブジェクトのrequest_uri
 
Client(RP)次第の実装  †
Discovery、Dynamic Client Registration  †
事前登録のない Client(RP) と IdP/STS(OP) 間の
予期しないやりとりをサポートすることを選択した場合に実装が必要。
セキュリティ  †
サーバ認証  †
ID Tokenの署名・暗号化で提供される。
トークン  †
- トークン生成
- JWT([[JWS])を使用する。
 
- TLS を使用する。
 
 
- アクセス許可の制限
aud の scope に対して制限をかける。 
- 有効期限の制限
code, access_token, refresh_token, 
- 置換攻撃の防止
- iss(完全一致)
 
- sub
 
- aud
 
- azp
 
- at_hash
 
- c_hash
 
 
暗号化  †
- 共通鍵暗号
HS256などのMACを使用する場合、client_secret は最低でも32オクテットが必要 
- 暗号関連の様々な攻撃
- タイミング・アタック
 
- JWT
- JWT の Security Considerations
 
- JWT が参照する, 各脆弱性を防ぐための仕様群
 
 
 
Requestオブジェクト  †
リクエストの漏洩や改ざんの防止
- 特に、max_age と acr_valuesなどの改ざん防止。
 
- 特に、claims や acr_valuesなどの漏洩防止
 
参考  †
- デジタル・アイデンティティ技術最新動向(4):「OpenID Connect」を理解する - @IT
 
OpenID Foundation  †
OpenID ファウンデーション・ジャパン  †
Client Implementer's Guide  †
WebアプリケーションのClientに当該フローを実装する場合の実装ガイド。
- OpenID Connect Client Implementer's Guide
 
Qiita  †
TakahikoKawasaki?  †
IdM実験室  †
WIF  †
WIF Extension for OAuthは古い?
OWIN  †
Microsoft.Owin.Security.OpenIdConnect?
ADFS  †
OpenID Connectのシーケンス  †
STEP 0 は事前準備なので、STEP 1 からが実際の認証・認可のシーケンス。
Webアプリ(Basic Client Profile)  †
- 概要
Basic Client Profile:OAuth 2.0 Authorization Code Grantを拡張 
- STEP 0 : 事前準備(IdP/STS(OP)にClient(RP)を登録)
- IdP/STS(OP)にClient(RP)を登録し、下記を入手する。
- アプリケーションID(client_id)
 
- シークレット(client_secret)
 
 
 
- STEP 1 : Authorization codeの取得
- Client(RP)がIdP/STS(OP)からAuthorization codeを取得。
 
- スターターのリクエストをIdP/STS(OP)に送信する。
 
 
- 上記のパラメタの説明
| # | パラメタ | 必須 | 説明 | 
| 1 | response_type | ○ | 「code」と「id_token」を指定 | 
| 2 | client_id | ○ | 事前に準備したclient_idの値を指定 | 
| 3 | redirect_uri | ○ | アプリケーションID登録時のコールバックURLに入力したURLを指定 | 
| 4 | state |  | CSRF対策のランダム文字列を指定 | 
| 5 | scope | ○ | ・openid:ユーザー識別子を取得(必須) ・profile:姓名・生年・性別が取得 ・email:メールアドレスと確認済みフラグを取得 ・address:ユーザー登録住所情報が取得 | 
| 6 | nonce | Implicit or Hybrid Flowでid_tokenを取得する際は必須 | リプレイアタック対策のランダム文字列を指定 | 
| 7 | display |  | ユーザのUIを選択: ・page(PC用UI、デフォルト値) ・touch(スマートフォン用UI) ・wap(フィーチャーフォン用UI) ・inapp(ネイティブアプリ用UI)~ | 
| 8 | その他、IdP/STS(OP)独自パラメタ |  | - | 
 
- 成功すると認証/認可の同意画面が表示される。
一度同意すると、次回以降、認証/認可の同意画面は省略される。 
- 認証/認可の同意が完了する(もしくは事前に認証/認可の同意をしている)と、
以下のようなURLで「・・・Client(RP)のURL・・・」にリダイレクトされる。
 
- STEP 2 : Access Token、ID Tokenの取得
- Tokenを取得する際は、POSTでリクエストを送信する
(HTTPリクエストのヘッダーやデータにTokenリクエストに必要な値を指定する必要がある)
ため、CUIのcURLコマンドを使用して、Access Token、ID Tokenを取得する。 
 
- cURLコマンドなどでリクエストする。
- 電文
| # | 部分 | 説明 | 
| 1 | Header | Authorization: Basic {basicAuth} | 
| 2 | URL | https://・・・IdP/STS(OP)のAccess Token、ID Token取得用のURL・・・?grant_type=authorization_code&code=・・・&redirect_uri=・・・" | 
 
 
- 上記のパラメタの説明
| # | パラメタ | 必須 | 説明 | 
| 1 | {basicAuth} | ○ | 基本認証を使用したクライアント認証のため、 アプリケーションID(client_id)、シークレット(client_secret)を":"区切りで結合しBase64文字列化 | 
| 2 | grant_type | ○ | authorization_code という固定文字列を指定 | 
| 3 | code | ○ | Authorization codeを指定、リクエスト送信後は使用できなくなる。 | 
| 4 | redirect_uri | ○ | STEP 1 のredirect_uriで指定したURLを入力。 | 
 
- 以下の様なレスポンスが返る。
- 電文
{
    "access_token":"{ヘッダー部}.{ペイロード部}.{シグネチャー部}",
    "token_type":"bearer",
    "expires_in":"3600",
    "refresh_token":"・・・",
    "id_token":"・・・"
} 
 
- STEP 3 : IDトークンの正当性の検証
- "access_token"の{ヘッダー部}を取り出して、base64デコード。
 
 
- {ヘッダー部}のパラメタの説明
| # | パラメタ | 説明 | 
| 1 | typ | typ:JWT(JSON Web Token) | 
| 2 | alg | alg:HMAC-SHA256(署名に使用したハッシュ) | 
 
- {ペイロード部}を取り出して、base64デコード。
- {ペイロード部}の電文
{
    "iss":"https:\/\/・・・Access Tokenの発行元URL・・・",
    "user_id":"ユーザー識別子",
    "aud":"アプリケーションID(client_id)と一致する値",
    "iat":IDトークンの発行時刻,
    "exp":IDトークンの有効期限,
    "nonce":"STEP 1 のnonceと一致する値"
} 
 
- 署名の検証
- "{ヘッダー部}.{ペイロード部}"を使用して、
{ヘッダー部}のalg:HMAC-SHA256でバイナリ形式でハッシュ化。 
- それをBase64文字列化した文字列が"{シグネチャー部}"と一致していることを確認する。
 
 
- STEP 4 : 属性情報の取得
Client(RP)がIdP/STS(OP)で認証したユーザ属性情報を取得する。 
- ユーザー情報エンドポイントに、以下の形式でAccess Tokenを渡す。
- 電文
| # | 部分 | 説明 | 
| 1 | Header | 'Authorization: Bearer {access_token}' | 
| 2 | URL | URL:https://・・・ユーザ属性情報の発行元URL・・・?schema=openid | 
 
 
- 上記のパラメタの説明
{access_token}に、準備、STEP 0-3 で取得したAccess Tokenを使う。 
- 以下のユーザ属性情報を含んだクレームが取得できる。
- 電文
{
    "user_id":"・・・",
    "name":"・・・",
    "given_name":"・・・",
    "given_name#ja-Kana-JP":"・・・",
    "given_name#ja-Hani-JP":"・・・",
    "family_name":"・・・",
    "family_name#ja-Kana-JP":"・・・",
    "family_name#ja-Hani-JP":"・・・",
    "gender":"male or female",
    "birthday":"YYYY",
    "locale":"ja-JP,etc."
} 
 
モバイルアプリ(Implicit Client Profile)  †
- 概要
- Implicit Client Profile:OAuth 2.0 Implicit Grantを拡張
 
- Webアプリ(Basic Client Profile)との違い
 
 
- STEP 0 : Discovery & Dynamic Client Registration
IdP/STS(OP)探索と動的なClient(RP)登録 
- IdP/STS(OP)探索
「○○のIDでログイン」というリンクを選択する替わりに、
次の2種類の値をIdP/STS(OP)特定(Discovery)のためのヒントとして利用できる。
 
- 動的なClient(RP)登録
Client(RP)登録用エンドポイントにPOSTリクエストを送ることで、
動的なClient(RP)登録(Dynamic Client Registration)もできる。 
結果的に、IdP/STS(OP)からClient(RP)識別のための“cient_id”がレスポンスされる。
- STEP 1 : Authorization Request
認可リクエスト 
- STEP 2 : Authorization Response
認可応答 
- STEP 3 : ID Token Verification
IDトークンの検証 
OpenId? Connectのサンプル  †
Microsoft.Owin.Security.OpenIdConnect?  †
AzureADに対して、OpenId? Connectを使用して認証する。
https://github.com/OpenTouryoProject/SampleProgram/tree/master/ASPNET/AuthN_AuthZ/OpenID_Connect/
- サンプル・アプリケーションをAzure Active Directoryに登録
- Azureの管理ポータルにサインイン。
 
- Azure Active Directoryのタブを開く。
 
- サンプル・アプリケーションを登録するテナント(ドメイン)を開く。
 
- [Applications]タブに移動し、ページの下部の[Add]アイコンををクリック。
 
- [What do you want to do?]画面で[Add an application my organization is developing]を選択。
 
- [Tell us about your application]画面が表示される。
- アプリケーションの名前を入力(例:OpenIDConnect_sample)。
 
- [Web Application and / or Web API]を選択する。
 
- [Next]をクリックする。
 
 
- [App properties]画面が表示される。
- サンプルのサインオンURLを入力(例:https://localhost:xxxxxx/)
サンプル・プロジェクトのプロパティにある開発サーバのSSL URLプロパティを指定
http://www.codeproject.com/Tips/766918/Visual-Studio-Use-HTTPS-SSL-On-Web-Application-Pro 
- アプリのID URIを入力(例:https://<your_tenant_name>/OpenIDConnect_sample)
'<your_tenant_name>はAzure ADのテナント(ドメイン)名。 
- [Complete]をクリック。
 
 
 
- サンプル・アプリケーションの構成
- web.configファイルを開く。
 
- FxTenant?にAzure ADのテナント(ドメイン)名を指定(例:xxxxx.onmicrosoft.com)
 
- FxClientId? にAzureのポータルから入手することができるClient IDを指定
- クライアントIDを取得するには、
 
- Azureの管理ポータルにサインイン。
 
- Azure Active Directoryのタブを開く。
 
- サンプル・アプリケーションを登録したテナント(ドメイン)を開く。
 
- [Applications]タブに移動しサンプル・アプリケーションを選択。
 
- アプリケーション画面で[ACCESS WEB APIS IN OTHER APPLICATIONS]を選択。
 
- Client IDをコピー。
 
 
- FxPostLogoutRedirectUri?にサンプルのサインオンURLを入力(例:https://localhost:xxxxxx/)
 
 
- サンプル・アプリケーションの実行
F5実行でリダイレクトされた先のAzure AD(IdP/STS(OP))で認証できることを確認する。
 
子ページ  †
Tags: :IT国際標準, :認証基盤, :クレームベース認証, :OAuth