「マイクロソフト系技術情報 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
ユースケースに対応するため、
多様な環境をサポートできる。
ざっくり、リクエスト→認証・認可→ユーザ情報を取得。
+--------+ +--------+ | | | | | |---------(1) AuthN Request-------->| | | | | | | | +--------+ | | | | | | | | | | | End- |<--(2) AuthN & AuthZ-->| | | | | User | | | | RP | | | | OP | | | +--------+ | | | | | | | |<--------(3) AuthN Response--------| | | | | | | |---------(4) UserInfo Request----->| | | | | | | |<--------(5) UserInfo Response-----| | | | | | +--------+ +--------+
OAuth 2.0との違いは、認証拡張機能が追加実装された点にある。
OAuth 2.0に認証結果とプロフィールの受渡し機能を追加。
OAuth 2.0 からのステップ上の拡張部分は無い。
ただし、
朱書きは、OAuth 2.0 からのステップ上の変更・拡張部分。
The Authorization Code Flow goes through the following steps.
朱書きは、OAuth 2.0 からのステップ上の変更・拡張部分。
The Implicit Flow follows the following steps:
ID トークンと同時に、アクセストークンや認可コードが一緒に発行される。
朱書きは、Authorization Code Flowとの差異。
The Hybrid Flow follows the following steps:
Hybrid Flowの場合、以下が必須。
その他、ユーザー属性クレーム群を格納する。
Idp(OP)は、扱うクレームの内容によって、
どちらを利用すべきかを判断する必要がある。
一定期間変更されないことが保証されており
キャッシュの効果があるものは集約クレーム。
クレームそのものではなく、問い合わせ先のURLを扱う。
をレスポンスに含む。
頻繁に更新されるものは分散クレーム。
GoogleでOpenID Connectの認証で取得したクレームセット。
(id_tokenそのものなのか?、ユーザー情報エンドポイントから取得したクレームか?)
{ "iss":"accounts.google.com", "at_hash":"・・・", ← Hybrid Flowの追加クレーム "email_verified":"true", "sub":"ユーザーの一意識別子", "azp":"認可された対象者のID.apps.googleusercontent.com", "email":"・・・・", "aud":"クライアント識別子.apps.googleusercontent.com", "iat":JWT の発行日時(Unix時間), "exp":JWT の有効期限(Unix時間) }
ココを見ると、これは恐らく、id_tokenなのだろうなと。
以下のGoogle公式のマニュアルにも記載があった。
項番 | グループ名 | 意味 | |
クレーム名 | |||
1 | sub | ユーザーの一意識別子 | |
2 | profile | プロフィール | |
2-1 | ・ | name | フルネーム |
2-2 | ・ | given_name | 名 |
2-3 | ・ | family_name | 姓 |
2-4 | ・ | middle_name | ミドルネーム |
2-5 | ・ | nickname | ニックネーム |
2-6 | ・ | preferred_username | 好みのユーザー名 |
2-7 | ・ | profile | プロフィールページの URL |
2-8 | ・ | picture | プロフィール画像の URL |
2-9 | ・ | website | Web サイトやブログの URL |
2-10 | ・ | gender | 性別。female と male が定義済み。 |
2-11 | ・ | birthdate | 誕生日。YYYY-MM-DD。 |
2-12 | ・ | zoneinfo | タイムゾーン。Europe/Paris など。 |
2-13 | ・ | locale | ロケール。en-US など。 |
2-14 | ・ | updated_at | 情報最終更新日。Unix エポックからの経過秒数。 |
3 | 電子メール | ||
3-1 | ・ | 電子メールアドレス | |
3-2 | ・ | email_verified | 電子メールアドレスが検証済みか否かの真偽値 |
4 | phone | 電話 | |
4-1 | ・ | phone_number | 電話番号 |
4-2 | ・ | phone_number_verified | 電話番号が検証済みか否かの真偽値 |
5 | address | 住所 JSON object。書式は「5.1.1. Address Claim」に記載。 | |
5-1 | ・ | formatted | フォーマットされたフルメールアドレス、表示用・郵送用に使用 |
5-2 | ・ | street_address | 通り・番地、号室、私書箱、複数行の拡張された住所情報。 |
5-3 | ・ | locality | City or locality |
5-4 | ・ | region | State, province, prefecture, or region. |
5-5 | ・ | postal_code | Zip code or postal code |
5-6 | ・ | country | Country name |
scope値によってユーザー属性クレーム群の格納要求を行うことができる。
前述のグループ名(profile, email, phone, address)をscope値に指定可能。
クレーム要求JSONの例を以下に示す:
{ "userinfo": { "given_name": {"essential": true}, "nickname": null, "email": {"essential": true}, "email_verified": {"essential": true}, "picture": null, "http://example.info/claims/groups": null }, "id_token": { "auth_time": {"essential": true}, "acr": {"values": ["urn:mace:incommon:iap:silver"] } } }
GET /userinfo HTTP/1.1 Host: server.exampletechinfoofmicrosofttech.osscons.jp Authorization: Bearer ・・・・・
HTTP/1.1 200 OK Content-Type: application/json { "sub": "ユーザID 的 な情報", "name": "Jane Doe", "given_name": "Jane", "family_name": "Doe", "preferred_username": "j.doe", "email": "janedoe@techinfoofmicrosofttech.osscons.jp", "picture": "http://techinfoofmicrosofttech.osscons.jp/janedoe/me.jpg" }
この仕様は、Discovery、Dynamic Client Registrationと関係がある。
比較的、重要度の高い仕様についてまとめる。
{ "userinfo": { "given_name": {"essential": true}, "nickname": null, "email": {"essential": true}, "email_verified": {"essential": true}, "picture": null, "http://example.info/claims/groups": null }, "id_token": { "auth_time": {"essential": true}, "acr": {"values": ["urn:mace:incommon:iap:silver"] } } }
クライアントアプリケーションは、認証コンテキストクラスを使用して、
ユーザー認証時に満たして欲しい認証コンテキストクラスを指定する。
Authentication Context Class Reference(ACR)識別子。
arcクレームを
要求できる。
WebアプリケーションのClientに当該フローを実装する場合の実装ガイド。
OAuth 2.0 Authorization Code Grantを拡張
OAuth 2.0 Implicit Grantを拡張
メールアドレスやURLからユーザが利用しているIdp(OP)を特定する方法
(Discoveryで発見したIdp(OP)に、)動的なRP登録を行う方法
Idp(OP)上でユーザーがログアウトしたときにRP側から検知する方法など、セッション管理の方法
WIF Extension for OAuthは古い?
Microsoft.Owin.Security.OpenIdConnect?
STEP 0 は事前準備なので、STEP 1 からが実際の認証・認可のシーケンス。
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=リプレイアタック対策のランダム文字列
# | パラメタ | 必須 | 説明 |
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 | id_tokenを取得する際は必須 | リプレイアタック対策のランダム文字列を指定 |
7 | display | ユーザのUIを選択: ・page(PC用UI、デフォルト値) ・touch(スマートフォン用UI) ・wap(フィーチャーフォン用UI) ・inapp(ネイティブアプリ用UI)~ | |
8 | その他、Idp(OP)独自パラメタ | - |
http://・・・RPのURL・・・?code=xxxxxxxx&state=CSRF対策のランダム文字列
# | パラメタ | 説明 |
1 | code | ”code=xxxxxxxx”を取得する。 |
2 | state | ”state=CSRF対策のランダム文字列”が、一致していることを確認する。 |
# | 部分 | 説明 |
1 | Header | Authorization: Basic {basicAuth} |
2 | URL | https://・・・Idp(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":"・・・" }
{ "typ":"JWT", "alg":"HS256" }
# | パラメタ | 説明 |
1 | typ | typ:JWT(JSON Web Token) |
2 | alg | alg:HMAC-SHA256(署名に使用したハッシュ) |
{ "iss":"https:\/\/・・・Access Tokenの発行元URL・・・", "user_id":"ユーザー識別子", "aud":"アプリケーションID(client_id)と一致する値", "iat":IDトークンの発行時刻, "exp":IDトークンの有効期限, "nonce":"STEP 1 のnonceと一致する値" }
# | 部分 | 説明 |
1 | Header | 'Authorization: Bearer {access_token}' |
2 | URL | 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." }
結果的に、OPからRP識別のための“cient_id”がレスポンスされる。
AzureADに対して、OpenId? Connectを使用して認証する。
https://github.com/OpenTouryoProject/SampleProgram/tree/master/ASPNET/OpenID_Connect/
- 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)で認証できることを確認する。
Tags: :認証基盤, :クレームベース認証, :OAuth