[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] -[[戻る>クレームベース認証#ya3d2a7b]] * 目次 [#tc83c978] #contents *概要 [#bb0360e2] -用途としては、「認証の仕様である」と言ってイイ。 -しかし技術的には、「『ID トークン』を発行するための仕様」と考えたほうがイイ。 **特徴 [#n9af5768] ***モジュラーデザイン [#he3af831] ユースケースに対応するため、 -複数の仕様から成り立っており、 -それらをモジュール的に組み合わせることで 多様な環境をサポートできる。 ***プロトコル概要 [#a4aac78c] ざっくり、リクエスト→認証・認可→ユーザ情報を取得。 +--------+ +--------+ | | | | | |---------(1) AuthN Request-------->| | | | | | | | +--------+ | | | | | | | | | | | End- |<--(2) AuthN & AuthZ-->| | | | | User | | | | RP | | | | OP | | | +--------+ | | | | | | | |<--------(3) AuthN Response--------| | | | | | | |---------(4) UserInfo Request----->| | | | | | | |<--------(5) UserInfo Response-----| | | | | | +--------+ +--------+ ***[[OAuth]] 2.0に認証拡張 [#u9589aff] [[OAuth]] 2.0との違いは、認証拡張機能が実装された点にある。 -[[OAuth]] 2.0では --認証機能(「認証Endpointから[[ユーザー属性クレーム群>#kb7212b1]]の取得する」)の仕様が無かった。 --このため、この部分の拡張仕様(認証Endpoint)に方言があり、実装上問題だった。 -これに対し[[OpenID Connect]]では、 --[[ユーザー属性クレーム群>#kb7212b1]]取得のEndpointがUserInfo Endpointに標準化された。 --これによって「認可」だけでなく「認証」の仕様も標準化された。 -OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜~ --OAuth 2.0 Authorization Code Flow~ http://www.slideshare.net/kura_lab/openid-connect-id/21 --OpenID Connect Authorization Code Flow~ http://www.slideshare.net/kura_lab/openid-connect-id/28 **仕様一覧 [#ie0f4645] ***[[OAuth]] 2.0に認証結果とプロフィールの受渡し機能を追加 [#c4eeb3ab] [[OAuth]] 2.0に認証結果とプロフィールの受渡し機能のみを追加した仕様 -Basic Client Profile~ http://openid.net/specs/openid-connect-basic-1_0.html >OAuth 2.0 Authorization Code Grantを拡張 -Implicit Client Profile~ http://openid.net/specs/openid-connect-implicit-1_0.html >OAuth 2.0 Implicit Grantを拡張 ***OpenID Connectのコアな機能(難しいことも可能に) [#wf00d0d3] リクエスト内の細かいクレーム指定や認証コンテキストの指定 -Messages~ http://openid.net/specs/openid-connect-messages-1_0.html >OAuth 2.0に追加で必要となるメッセージの使用 -Standard~ http://openid.net/specs/openid-connect-standard-1_0.html >Messagesの内容をHTTPに落とし込んだHTTPバインディング仕様 ***関連仕様 [#h5793a09] -Discovery~ http://openid.net/specs/openid-connect-discovery-1_0.html >メールアドレスやURLからユーザが利用しているOPを特定する方法 -Dynamic Client Registration~ http://openid.net/specs/openid-connect-registration-1_0.html >動的なRP登録を行う方法 -Session Management~ http://openid.net/specs/openid-connect-session-1_0.html >Idp(OP)上でユーザーがログアウトしたときにRP側から検知する方法など、セッション管理の方法 **認証のシーケンス [#p1446f50] ***Authorization Code Flow [#mcde509a] [[OAuth]] 2.0 からのステップ上の拡張部分は無い。~ ただし、アクセス先がResources ServerのEndpointがUserInfo Endpointに特定されており、~ ここから、認証されたユーザ情報として[[ユーザー属性クレーム群>#kb7212b1]]を取得している。 -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. -[[以下で説明しているシーケンス>#h438d001]] ***Implicit Flow [#e7adf5c2] 朱書きは、[[OAuth]] 2.0 からのステップ上の変更・拡張部分。~ ポイントは、User-Agentやスマホネイティブから直接的にAccess Tokenを使用せず、~ ClientにAccess Tokenを送って、そこから[[ユーザー属性クレーム群>#kb7212b1]]を取得している点。 -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. +&color(red){Client validates the ID token and retrieves the End-User's Subject Identifier.}; -[[以下で説明しているシーケンス>#v2c717b3]] ***Hybrid Flow [#l565139a] 朱書きは、[[Authorization Code Flow>#mcde509a]]との差異。~ ID トークンと同時に、アクセストークンや認可コードが一緒に発行される場合、~ ID トークンにat_hash、c_hashクレームが追加される(用途不明)。 -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,~ &color(red){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. *IDトークン(クレーム) [#ofb73c59] -Final: OpenID Connect Core 1.0 incorporating errata set 1~ http://openid.net/specs/openid-connect-core-1_0.html --2. ID Token~ http://openid.net/specs/openid-connect-core-1_0.html#IDToken --3.3.2.11. ID Token (Hybrid Flow)~ http://openid.net/specs/openid-connect-core-1_0.html#HybridIDToken **概要 [#fe1155a7] -OpenID Connect で [[OAuth]] 2.0 を拡張した主要なクレームが、ID トークン。 -以下のクレームの値を含むクレームセット。 --発行元のIdp(OP)識別子 --発行先のRP識別子(client_id) --ユーザー識別子 --発行日時 -仕様全体を通してメッセージ形式にJSONを採用。 -クレームの扱いについて次のような機能を定義している。 --外部クレームの提供 ---集約クレーム(Aggregated Claims) ---分散クレーム(Distributed Claims) --クレームの暗号化(Encrypted Claims) **ID トークンは [[JWT]] の一種 [#k7a01d90] ***メッセージ形式にJSONを採用 [#ldcbc3dc] [[JWT]] : JSON Web Tokenの略 ***クレーム暗号化 [#vfd3c786] [[JWT]]のJWS or JWEを使用する。 **クレームセット [#h586dfab] ***必須クレーム群 [#ffe4c45b] -iss (issuer) クレーム --([[OAuth]] 2.0で言う所の)AuthorizationServerの識別子。 --URI形式が推奨 これは、OpenID Connect Discovery 1.0 仕様をサポートするのであれば、~ 「{issクレームの値}/.well-known/openid-configuration」という URL で~ リクエストを受け付ける必要があるため。 -sub (subject) クレーム~ ユーザーテーブルのプライマリーキーやそれに準ずるもの。 -aud (audience) クレーム~ ([[OAuth]] 2.0で言う所の)クライアント識別子。 -exp (expiration time) クレーム --JWT の有効期限 --Unix エポックからの経過秒数(ミリ秒ではなく秒) -iat (issued at)クレーム --JWT の発行日時 --Unix エポックからの経過秒数(ミリ秒ではなく秒) ***ケースバイケースなクレーム群 [#d9a64ea2] -auth_time クレーム --ユーザー認証時刻 --Unix エポックからの経過秒数(ミリ秒ではなく秒) --リクエストパラメータやメタ情報設定次第で必須となるもよう。 -[[nonce>https://ja.wikipedia.org/wiki/%E3%83%8E%E3%83%B3%E3%82%B9]] クレーム --リプレイアタック防止を目的とするクレーム。 --ID トークン発行依頼に付属するnonce 値を、そのまま埋め込む。 --Implicit Flowの場合は必須となるもよう。 ***オプションのクレーム群 [#l52144f8] -acr クレーム --認証コンテキストのクラス --必要に応じて再認証を催す。 --仕様で幾つか定義されているらしいが詳細不明。 -amr クレーム --認証手法を示す。 --利用用途が不明。 --仕様範囲外、クレームの利用者が規則を決めて運用する。 -azp クレーム --認可された対象者 --認証されたユーザと認可されたユーザが違うケースを想定している模様。 **外部クレーム [#jb63c82f] Idp(OP)は、扱うクレームの内容によって、 -集約クレーム -分散クレーム どちらを利用すべきかを判断する必要がある。 ***集約クレーム [#yfd0840d] -別のIdp(OP)が持つクレームを署名付きで提供すること。 -RPからリクエストを受けたIdp(OP)は、事前に取得していた、~ もしくは動的に取得した別のIdp(OP)のクレームをレスポンスに含む。 一定期間変更されないことが保証されており~ キャッシュの効果があるものは集約クレーム。 ***分散クレーム [#xaa4e17c] クレームそのものではなく、問い合わせ先のURLを扱う。 -Publicなクレームの場合 --エンドポイントのURL -ユーザー認可が必要な場合 --エンドポイントのURL --OAuth 2.0のアクセストークン をレスポンスに含む。 頻繁に更新されるものは分散クレーム。 *ユーザー属性クレーム群 [#kb7212b1] -Final: OpenID Connect Core 1.0 incorporating errata set 1 > 5.1. Standard Claims~ http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims **多言語化 [#u1556f80] -クレームによっては多言語化可能 -クレーム名の後に *OpenID Connectのシーケンス [#s55b276e] STEP 0 は事前準備なので、STEP 1 からが実際の認証・認可のシーケンス。 **Webアプリ(Basic Client Profile) [#h438d001] -Basic Client Profile:OAuth 2.0 Authorization Code Grantを拡張 -デジタル・アイデンティティ技術最新動向(4):「OpenID Connect」を理解する (1/2) - @IT~ http://www.atmarkit.co.jp/ait/articles/1209/27/news138.html -OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜~ OpenID Connect Authorization Code Flow~ http://www.slideshare.net/kura_lab/openid-connect-id/28 -OpenID Connect体験 - Qiita~ http://qiita.com/sonedazaurus/items/753a65186f1be7185b39 ***STEP 0 : 事前準備(Idp(OP)にRPを登録) [#uc0ae497] Idp(OP)にRPを登録し、 -アプリケーションID(client_id) -シークレット(client_secret) を入手する。 -参考 --Yahoo! JAPAN IDの登録ページ~ https://account.edit.yahoo.co.jp/registration --アプリケーションIDの登録ページ~ https://e.developer.yahoo.co.jp/register ***STEP 1 : Authorization codeの取得 [#w6d2830e] RPがIdp(OP)からAuthorization codeを取得。 -リクエスト https://・・・Idp(OP)のAuthorization code取得用のURL・・・? response_type=code+id_token &client_id={client_id} &redirect_uri=・・・RPのURL・・・ &state=CSRF対策のランダム文字列 &scope=openid+profile &nonce=リプレイアタック対策のランダム文字列 -パラメタ |パラメータ|必須|説明|h |response_type|○|「code」と「id_token」を指定| |client_id|○|事前に準備したclient_idの値を指定| |redirect_uri|○|アプリケーションID登録時のコールバックURLに入力したURLを指定| |state||CSRF対策のランダム文字列を指定| |scope|○|・openid:ユーザー識別子を取得(必須)&br;・profile:姓名・生年・性別が取得&br;・email:メールアドレスと確認済みフラグを取得&br;・address:ユーザー登録住所情報が取得| |nonce|id_tokenを取得する際は必須|リプレイアタック対策のランダム文字列を指定| |display||ユーザのUIを選択:&br;・page(PC用UI、デフォルト値)&br;・touch(スマートフォン用UI)&br;・wap(フィーチャーフォン用UI)&br;・inapp(ネイティブアプリ用UI)~| |その他、Idp(OP)独自パラメタ||-| -成功するとログイン/同意画面が表示される。~ 一度同意すると、次回以降同意画面は省略される。 -ログイン/同意が完了する(もしくは事前にログイン、同意している)と、~ 以下のようなURLで「・・・RPのURL・・・」にリダイレクトされる。 http://・・・RPのURL・・・?code=xxxxxxxx&state=CSRF対策のランダム文字列 --”code=xxxxxxxx”が、Authorization codeなので保存する。 --”state=CSRF対策のランダム文字列”が、一致していることを確認する。 ***STEP 2 : Access Token、ID Tokenの取得 [#ma165906] -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=・・・" -- |パラメータ|必須|説明|h |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トークンの正当性の検証 [#a2c91dd5] "access_token"の -{ヘッダー部}を取り出して、base64デコード。~ { "typ":"JWT", "alg":"HS256" } --typ:JWT(JSON Web Token) --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 : 属性情報の取得 [#v5e6dad3] -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." } **モバイルアプリ(Implicit Client Profile) [#v2c717b3] -Implicit Client Profile:OAuth 2.0 Implicit Grantを拡張 -参考 --デジタル・アイデンティティ技術最新動向(4):「OpenID Connect」を理解する (2/2) - @IT~ http://www.atmarkit.co.jp/ait/articles/1209/27/news138_2.html -Webアプリ(Basic Client Profile)との違い --STEP 0は、前提の違いによる差異。 --STEP 1以降は、Implicit Flowがベースとなっている。 ***STEP 0 : Discovery & Dynamic Client Registration [#l8e54863] IdP(OP)探索と動的なRP登録 -「○○のIDでログイン」というリンクを選択する替わりに、~ 次の2種類の値をIdP(OP)特定(Discovery)のためのヒントとして利用できる。 --メールアドレス~ 例 : ritou@openidconnect.info --OP URL~ 例 : https://openidconnect.info -動的なRP登録~ RP登録用エンドポイントにPOSTリクエストを送ることで、~ 動的なRP登録(Dynamic Client Registration)もできる。 結果的に、OPからRP識別のための“cient_id”がレスポンスされる。 ***STEP 1 : Authorization Request [#q48280b8] 認可リクエスト ***STEP 2 : Authorization Response [#g13ce252] 認可応答 ***STEP 3 : ID Token Verification [#b8e5b481] IDトークンの検証 ***STEP 4 : Accessing to UserInfo Endpoint [#c0d0225d] UserInfoエンドポイントへのアクセス *参考 [#p95f33f1] -なぜOpenID Connectが必要となったのか、その歴史的背景~ http://www.slideshare.net/tkudo/openid-connect-devlove?next_slideshow=1 -超速習 OpenID Connect - Qiita~ http://qiita.com/sylph01/items/208ae313c03426feedc1 -第一回 認証基盤のこれからを支えるOpenID Connect | オブジェクトの広場~ https://www.ogis-ri.co.jp/otc/hiroba/technical/openid-connect/chap1.html -デジタル・アイデンティティ技術最新動向(4):「OpenID Connect」を理解する - @IT --http://www.atmarkit.co.jp/ait/articles/1209/27/news138.html --http://www.atmarkit.co.jp/ait/articles/1209/27/news138_2.html -OpenID Connect 入門 〜コンシューマーにおけるID連携のトレンド〜~ http://www.slideshare.net/kura_lab/openid-connect-id -[前編] IDトークンが分かれば OpenID Connect が分かる - Qiita~ http://qiita.com/TakahikoKawasaki/items/8f0e422c7edd2d220e06 -OpenID Connectはそんなに大変かね? - OAuth.jp~ http://oauth.jp/blog/2016/02/24/is-openid-connect-far-from-oauth2/ -エンタープライズITでのOpenID Connect利用ガイドライン~ http://www.slideshare.net/tkudo/openid-connect-for-enterprise **OpenID Foundation [#z4c28dbb] -OpenID Connect | OpenID~ http://openid.net/connect/ -公開資料 | OpenID ファウンデーション・ジャパン~ http://www.openid.or.jp/document/ -Final: OpenID Connect Core 1.0 incorporating errata set 1~ http://openid.net/specs/openid-connect-core-1_0.html --Final: OpenID Connect Discovery 1.0 incorporating errata set 1~ https://openid.net/specs/openid-connect-discovery-1_0.html --Final: OpenID Connect Dynamic Client Registration 1.0 incorporating errata set 1~ https://openid.net/specs/openid-connect-registration-1_0.html **IdM実験室 [#l12e411e] ***WIF [#p153dc92] -IdM実験室 WIF Extension for OAuth を使って OpenID Connect を体験~ http://idmlab.eidentity.jp/2012/03/wif-extension-for-oauth-openid-connect.html WIF Extension for OAuthは古い? ***OWIN [#x00c009d] Microsoft.Owin.Security.OpenIdConnect -IdM実験室: [AAD/ASP.NET] OpenID Connectを使ってAADでログオンする~ http://idmlab.eidentity.jp/2014/05/aadaspnet-openid-connectaad.html -Ad(microsoftの方)のOpenId Connect対応~ http://www.slideshare.net/naohiro.fujie/admicrosoftopen-id-connect ***ADFS [#hcd0bd22] -IdM実験室: [AD FS]OpenID Connectに対応した次期AD FSを試す~ http://idmlab.eidentity.jp/2015/08/ad-fsopenid-connectad-fs.html **Tsmatz [#x416a34b] -v2.0 endpoint の OAuth を使った Client 開発 (Azure AD と MSA への対応) – Tsmatz~ https://blogs.msdn.microsoft.com/tsmatsuz/2016/02/24/v2-endpoint-oauth2-client-using-azure-active-directory-and-microsoft-account/ -v2.0 endpoint の JavaScript Client 開発 (OAuth Implicit Grant Flow) – Tsmatz~ https://blogs.msdn.microsoft.com/tsmatsuz/2016/03/02/azure-ad-msa-v2-endpoint-javascript-app-using-oauth-implicit-grant/ -How to use Application Permission with v2 endpoint and Microsoft Graph – Tsmatz~ https://blogs.msdn.microsoft.com/tsmatsuz/2016/10/07/application-permission-with-v2-endpoint-and-microsoft-graph/ -v2.0 endpoint の OAuth Token の検証 (Verify) – Tsmatz~ https://blogs.msdn.microsoft.com/tsmatsuz/2016/03/08/azure-ad-msa-v2-endpoint-validate-id_token/ 上記のコンテンツの内容を確認すると、 -Microsoft の組織アカウント (Azure Active Directory, Azure AD) と -個人アカウント (Microsoft Account, MSA) の 双方に対応した v2.0 endpoint (App Model v2) と連携し、~ [[OAuth]] 2.0(ではなく、OpenID Connect)認証をおこない、~ 認証結果を他の API (Service) で検証し認証させている。 *サンプルを実行する方法 [#l2d6ff73] **Microsoft.Owin.Security.OpenIdConnect [#i4f26644] https://github.com/OpenTouryoProject/SampleProgram/tree/master/ASPNET/OpenID_Connect/ ***サンプル・アプリケーションをAzure Active Directoryに登録 [#m0e0f2c0] +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]をクリック。 ***サンプル・アプリケーションの構成 [#a7737c8d] +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/) ***サンプル・アプリケーションの構成 [#t8486caa] F5実行でリダイレクトされた先のAzure AD(STS)で認証できることを確認する。 ---- Tags: [[:認証基盤]], [[:クレームベース認証]]