※ Azure AD v1 endpoint に関する内容です (v2 endpoint の場合は、こちら を参照してください)
開発者にとっての Azure Active Directory (Microsoft Entra ID)
- Azure Active Directory とは (事前準備)
- Web SSO 開発 – .NET 編 (WS-Fed)
- Web SSO 開発 – PHP, Node.js 編 (SAML) ※英語
- SaaS 連携 : Google Apps (SAML)
- SaaS 連携 : kintone (SAML)
- OpenID Connect サポート (OpenID)
- OAuth による Client の開発 (OAuth)
- OAuth による Service の開発 (OAuth)
- Common Consent Framework – Client 側 (OAuth)
- Common Consent Framework – Service 側 (OAuth)
- Application Role の使用 (OAuth)
- Backend Server-Side アプリの開発 (OAuth)
- Federated Credentials (OAuth) ※英語
- Login UI が表示できない場合のフロー (OAuth)
- JavaScript Application の開発 (OAuth)
- Windows 10 との SSO 開発 (Web Account Manager API)
- Active Directory (企業内 Windows 環境) との Federation と同期
- Multi-Factor Authentication
- Graph API
こんにちは。
OpenID Connect (標準) の正式リリースと共に、Microsoft Azure Active Directory の OpenID Connect 実装も公開されました。(現在、このサポートは Preview 版ですのでご注意ください。)
いま、実は、勉強会に参加しているのですが、Azure AD の OpenID Connect に関するドキュメントがあまりないようなので、以下に記載しておきたいと思います。(基本的には OpenID Connect そのものですが、まだ、一部使えないプロパティなどもあるようなので、一般的な流れを記載しておきます。実際に動かしたログから記載しています。)
事前準備
まず、あらかじめ、「Azure AD を使った API 連携の Client 開発 (OAuth 2.0 紹介)」で紹介している手順で、Azure Portal を使用して、Azure Active Directory のテナントに Application (Relying Party, Consumer) を登録しておきます。(今回、Application の Uri を http://localhost:1384/ と仮定します。)
なお、この際、Application の client id をメモしておいてください。
Login Flow
では、上記で登録した Application を使って認証フローを確認します。
まず、やり取りをおこなうために、接続先 (endpoint) などの基本情報が必要になりますが、OpenID Connect では、これらの情報は Discovery を使って取得できます。
下記の通り、Issuer の /.well-known/openid-configuration の Uri にアクセスします。
GET https://login.microsoftonline.com/aadsample.onmicrosoft.com/.well-known/openid-configuration
上記の Response Body として、下記のような Json フォーマットの情報が返ってきます。
下記には、これから使用するエンドポイントの情報が入っています。また、サポートされている response_type の情報 (response_types_supported) なども記述されているため、例えば、「response_type として『token』(Access Token) は使えない」といったこともわかります。Application 側 (Client, Relying Party, Consumer) では、この情報に基づいて認証の要求をおこないます。
{ "issuer":"https://sts.windows.net/6cf16624-15f0-4157-8cde-963a80d854bd/", "authorization_endpoint":"https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/authorize", "token_endpoint":"https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/token", "token_endpoint_auth_methods_supported": ["client_secret_post","private_key_jwt" ], "jwks_uri":"https://login.microsoftonline.com/common/discovery/keys", "response_types_supported": ["code","id_token","code id_token" ], "response_modes_supported": ["query","fragment","form_post" ], "subject_types_supported":["pairwise"], "scopes_supported":["openid"], "id_token_signing_alg_values_supported":["RS256"], "microsoft_multi_refresh_token":true, "check_session_iframe":"https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/checksession", "end_session_endpoint":"https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/logout"}
ブラウザーを使用して、上記の token_endpoint を元に、下記の通りトークンを要求します。(なお、上記の 6cf16624-15f0-4157-8cde-963a80d854bd は、私が使用しているテナントの tenant id です。tenant id については「Azure Active Directory と事前準備」を参照してください。) client_id は、上記でコピーした値を設定します。
今回は、response_type を見ておわかりの通り、Authorization Code と ID Token を要求しています。(Access Token ではありません。)
nonce は、プログラムなどを使用したアタック (Reply Attack) を防ぐために使用する任意の文字列で、このあと返ってくる token の中にもそのまま含まれます。(ここでは nonce の詳細説明を省略します。「@IT : OpenIDをとりまくセキュリティ上の脅威とその対策」が参考になります。)
また、state には、この後、認証を終えて Redirect される際に保持しておく任意の情報を設定できます。
GET https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/authorize?client_id=63d11d91-eb30-4f53-9f8a-a298845b39fe&response_mode=form_post&response_type=code+id_token&scope=openid+profile&nonce=... &state=...
上記の URL にアクセスすると、いつもの Azure AD の Login 画面が表示 (リダイレクト) されるので、アカウント情報を入力してサインインします。
ログインに成功すると、下記の通り、code と id_token が返されます。(state には、上記で指定した値がそのまま返ってきます。)
POST http://localhost:1384/Content-Type: application/x-www-form-urlencodedcode=AwABAAAAvPM1KaPlrEqdFS...&id_token=eyJ0eXAiOiJKV1QiLC...&state=&session_state=e91f9d0b-303b-411d-a2c3-0e243a9ebf65
OpenID は OAuth の方式をベースとしています。
ここで返される code は「Azure AD を使った API (Service) 連携の Client 開発」で解説した OAuth のauthorization code です。つまり、この code を使って Access Token を取得し、server-to-server シナリオで Exchange Online やカスタムの Web API などの必要なリソースに接続できます。
補足 : code を使って「Azure AD を使った API (Service) 連携の Client 開発」と同じ手順でリソースにアクセスには、下記の通り、client_secret と resource を指定して Access Token を要求します。(下記は、Exchange Online にアクセスする場合の記述例です。Client Secret は Microsoft Azure Management Portal で作成できます。)
POST https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/tokenContent-Type: application/x-www-form-urlencodedgrant_type=authorization_code&code=AwABAAAAvPM1KaPlrEqd...&client_id=63d11d91-eb30-4f53-9f8a-a298845b39fe&client_secret=AxoffBO07%2f%2f%2f3oAi... &resource=https%3a%2f%2foutlook.office365.com%2f&redirect_uri=http%3a%2f%2flocalhost%3a1384%2f
また、上記の id_token はエンコードされた JSON オブジェクトです。下記の 3 つの内容が「.」(dot) で区切られて入っており、「OAuth 2 Token (JWT) の Decode」の方法で Encode されています。
3 つのうちの最初は、署名に関する基本情報で、x5t には thumbprint が入っています。
2 番目がトークン本体で、c_hash に Code hash と呼ばれる情報が入っています。(下記の通り、Audience (ログインしたユーザー) の Id や、トークンの有効期限、上述の nonce の情報なども入っています。)
そして、3 番目に署名が入っています。
{ "typ":"JWT", "alg":"RS256", "x5t":"NGTFvdK-fythEuL ..."}
{ "aud":"63d11d91-eb30-4f53-9f8a-a298845b39fe", "iss":"https://sts.windows.net/6cf16624-15f0-4157-8cde-963a80d854bd/", "iat":1397713274, "nbf":1397713274, "exp":1397717174, "ver":"1.0", "tid":"6cf16624-15f0-4157-8cde-963a80d854bd", "oid":"5b42055f-55f7-4d8f-9c19-5d65ea16273c", "upn":"tsmatsuz@aadsample.onmicrosoft.com", "unique_name":"tsmatsuz@aadsample.onmicrosoft.com", "sub":"H_Hsx_iAfzJnXSD7VKhK129ufbMfm73L8_RmmTEi5Y0", "family_name":"Matsuzaki", "given_name":"Tsuyoshi", "nonce":"", "c_hash":"UpveSNROPOhhKEZJL ..."}
mU8jykngs6-U1hpYoz7tjTwbz ...
Application (Client, Consumer, Relying Party) では、この取得した c_hash が正しい IdP から発行されたものかどうかの検証する必要があります。
検証は、上記 (/.well-known/openid-configuration) の jwks_uri の Uri から取得できるキーの情報を元にローカルで検証できるので、あらかじめ、下記の通り、このキーの情報を取得してクライアント (Consumer, Relying Party) で保持しておくと良いでしょう。
この検証方法については「Azure AD : Service 開発 (access token の verify)」に記載しましたので参考にしてください。
GET https://login.microsoftonline.com/common/discovery/keys
上記の Response Body は以下の通りです。
{ "keys": [{ "kty":"RSA", "use":"sig", "kid":"NGTFvdK-fythEuL...", "x5t":"NGTFvdK-fythEuL...", "n":"rCz8Sn3GGXmikH2...", "e":"AQAB", "x5c": ["MIIDPjCCAiqgAwIBA..." ]},{ "kty":"RSA", "use":"sig", "kid":"kriMPdmBvx68skT...", "x5t":"kriMPdmBvx68skT...", "n":"kSCWg6q9iYxvJE2...", "e":"AQAB", "x5c": ["MIIDPjCCAiqgAwIBA..." ]} ]}
また、Application 側 (Client, Consumer, Relying Party) では、前述の通り、プログラムなどによる Reply Attack に備え、nonce を確認し、問題なければ nonce の情報を削除するなどの実装をおこないます。(繰り返し攻撃されないように、nonce を破棄しておきます。)
さいごに、アカウントから Sign Out (logout) をおこなって、ブラウザーに残った Cookie などをクリアする場合には、下記のとおり post_logout_redirect_uri に戻り先の URL を設定してブラウザーでアクセスします。(logout が完了すると、post_logout_redirect_uri に戻ってきます。)
https://login.microsoftonline.com/6cf16624-15f0-4157-8cde-963a80d854bd/oauth2/logout?post_logout_redirect_uri=http%3A%2F%2Flocalhost%3A1384
OpenID Connect の詳細は、下記の Spec を参照してみてください。
[参考] OpenID Connect Discovery
http://openid.net/specs/openid-connect-discovery-1_0-21.html
[参考] OpenID Connect Messages
http://openid.net/specs/openid-connect-messages-1_0-20.html
※ 変更履歴 :
2017/05/26 画面を新ポータル (https://portal.azure.com) に変更
Categories: Uncategorized
2 replies»