Uncategorized

Azure AD (Entra ID) の OpenID Connect サポート

※ Azure AD v1 endpoint に関する内容です (v2 endpoint の場合は、こちら を参照してください)

開発者にとっての Azure Active Directory (Microsoft Entra ID)

こんにちは。

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

Tagged as: , ,

2 replies»

Leave a Reply