Open棟梁Project - マイクロソフト系技術情報 Wiki
目次  †
概要  †
モジュラーデザイン  †
ユースケースに対応するため、
- 複数の仕様から成り立っており、
 
- それらをモジュール的に組み合わせることで
 
多様な環境をサポートできる。
仕様一覧  †
OAuth 2.0に認証結果とプロフィールの受渡し機能を追加  †
OAuth 2.0に認証結果とプロフィールの受渡し機能のみを追加した仕様
OpenID Connectのコアな機能(難しいことも可能に)  †
リクエスト内の細かいクレーム指定や認証コンテキストの指定
関連仕様  †
3つの認証のシーケンス  †
Authorization Code Flow  †
以下で説明しているシーケンス
Implicit Flow  †
ネイティブアプリやJavaScriptが使用するシーケンス。
Hybrid Flow  †
SAMLやOpenID Connectの組合せのシーケンス?
OpenIDトークン(クレーム)  †
- 以下の値を含むデータをエンコードして署名を付けたもの。
- 発行元のIdp(OP)識別子
 
- 発行先のRP識別子(client_id)
 
- ユーザー識別子
 
- 発行日時
 
 
- クレームの扱いについて次のような機能を定義している。
- 外部クレームの提供
- 集約クレーム(Aggregated Claims)
 
- 分散クレーム(Distributed Claims)
 
 
- クレームの暗号化(Encrypted Claims)
 
 
外部クレーム  †
Idp(OP)は、扱うクレームの内容によって、
どちらを利用すべきかを判断する必要がある。
集約クレーム  †
- 別のIdp(OP)が持つクレームを署名付きで提供すること。
 
- RPからリクエストを受けたIdp(OP)は、事前に取得していた、
もしくは動的に取得した別のIdp(OP)のクレームをレスポンスに含む。 
一定期間変更されないことが保証されており
キャッシュの効果があるものは集約クレーム。
分散クレーム  †
クレームそのものではなく、問い合わせ先のURLを扱う。
- ユーザー認可が必要な場合
- エンドポイントのURL
 
- OAuth 2.0のアクセストークン
 
 
をレスポンスに含む。
頻繁に更新されるものは分散クレーム。
クレーム暗号化  †
クレーム(JSONデータ)の
の方法は、IETFのJOSE WGにて仕様が策定されている。
JSON Web Signature(JWS)  †
JSON Web Encryption(JWE)  †
JSONデータで表現されたクレームを、
- Idp(OP):暗号化する。
 
- Idp(OP):RPにリダイレクトして渡す。
 
- RP:復号化する。
 
OpenID Connectのシーケンス  †
STEP 0 は事前準備なので、STEP 1 からが実際の認証・認可のシーケンス。
Webアプリ  †
STEP 0 : 事前準備(Idp(OP)にRPを登録)  †
Idp(OP)にRPを登録し、
- アプリケーションID(client_id)
 
- シークレット(client_secret)
 
を入手する。
STEP 1 : Authorization codeの取得  †
RPがIdp(OP)からAuthorization codeを取得。
- パラメタ
| パラメータ | 必須 | 説明 | 
| response_type | ○ | 「code」と「id_token」を指定 | 
| client_id | ○ | 事前に準備したclient_idの値を指定 | 
| redirect_uri | ○ | アプリケーションID登録時のコールバックURLに入力したURLを指定 | 
| state |  | CSRF対策のランダム文字列を指定 | 
| scope | ○ | ・openid:ユーザー識別子を取得(必須) ・profile:姓名・生年・性別が取得 ・email:メールアドレスと確認済みフラグを取得 ・address:ユーザー登録住所情報が取得 | 
| nonce | id_tokenを取得する際は必須 | リプレイアタック対策のランダム文字列を指定 | 
| display |  | ユーザのUIを選択: ・page(PC用UI、デフォルト値) ・touch(スマートフォン用UI) ・wap(フィーチャーフォン用UI) ・inapp(ネイティブアプリ用UI)~ | 
| その他、Idp(OP)独自パラメタ |  | - | 
 
- 成功するとログイン/同意画面が表示される。
一度同意すると、次回以降同意画面は省略される。 
- ”code=xxxxxxxx”が、Authorization codeなので保存する。
 
- ”state=CSRF対策のランダム文字列”が、一致していることを確認する。
 
STEP 2 : Access Token、ID Tokenの取得  †
- Tokenを取得する際は、POSTでリクエストを送信(HTTPリクエストのヘッダーやデータにTokenリクエストに必要な値を指定する必要がある)ため、CUIのcURLコマンドを使用して、Access Token、ID Tokenを取得する。
 
- cURLコマンドなどでリクエストする。
- Header:'Authorization: Basic {basicAuth}'
 
- URL:https://・・・Idp(OP)のAccess Token、ID Token取得用のURL・・・?grant_type=authorization_code&code=・・・&redirect_uri=・・・"
| パラメータ | 必須 | 説明 | 
| grant_type | ○ | authorization_code という固定文字列を指定 | 
| code | ○ | Authorization codeを指定、リクエスト送信後は使用できなくなる。 | 
| redirect_uri | ○ | STEP 1 のredirect_uriで指定したURLを入力。 | 
 
 
- 基本認証が必要になる。
- アプリケーションID(client_id)
 
- シークレット(client_secret)
 
- 上記を":"区切りで結合しBase64文字列化
 
 
- 以下の様なレスポンスが返る。
{
"access_token":"{ヘッダー部}.{ペイロード部}.{シグネチャー部}",
"token_type":"bearer",
"expires_in":"3600",
"refresh_token":"・・・",
"id_token":"・・・"
} 
STEP 3 : IDトークンの正当性の検証  †
"access_token"の
- {ペイロード部}を取り出して、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 : 属性情報の取得  †
- RPがIdP(OP)で認証したユーザ属性情報を取得する。
 
- ここで、準備、STEP 0-3 で取得したAccess Tokenを使う。
 
- UserInfoAPIに、以下の形式でAccess Tokenを渡す。
- Header:'Authorization: Bearer {access_token}'
 
- URL:https://・・・ユーザ属性情報の発行元URL・・・?schema=openid
 
 
- 以下のユーザ属性情報を含んだクレームが取得できる。
{
"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."
} 
モバイルアプリ  †
STEP 1以降のモバイルアプリにおける差異が不明だった。
STEP 0 : Discovery & Dynamic Client Registration  †
IdP(OP)探索と動的なRP登録
- 「○○のIDでログイン」というリンクを選択する替わりに、
次の2種類の値をIdP(OP)特定(Discovery)のためのヒントとして利用できる。
 
- 動的なRP登録
RP登録用エンドポイントにPOSTリクエストを送ることで、
動的なRP登録(Dynamic Client Registration)もできる。 
結果的に、OPからRP識別のための“cient_id”がレスポンスされる。
STEP 1 : Authorization Request  †
認可リクエスト
STEP 2 : Authorization Response  †
認可応答
STEP 3 : ID Token Verification  †
IDトークンの検証
STEP 4 : Accessing to UserInfo? Endpoint  †
UserInfo?エンドポイントへのアクセス
参考  †
IdM実験室  †
WIF  †
WIF Extension for OAuthは古い?
OWIN  †
Microsoft.Owin.Security.OpenIdConnect?
ADFS  †
サンプルを実行する方法  †
Microsoft.Owin.Security.OpenIdConnect?  †
https://github.com/OpenTouryoProject/SampleProgram/tree/master/ASPNET/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(STS)で認証できることを確認する。