Azure AD の OpenID Connect サポート


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

開発者にとっての Microsoft Azure Active Directory

こんにちは。

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=401be184-8e53-4a30-8368-6b78bfe4f650&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-urlencoded

code=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/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=AwABAAAAvPM1KaPlrEqd...&client_id=401be184-8e53-4a30-8368-6b78bfe4f650&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":"401be184-8e53-4a30-8368-6b78bfe4f650",
  "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

Comments (0)

Skip to main content