Azure ADのIDトークンを取得し、クレームを確認する

2021.09.12

いわさです。

Azure ADはOpenID Connect(OIDC)に対応しています。

Azure ADのOAuth2, OIDCのトークン周りを少し調べる必要があったので、まずはOIDCにてIDトークンを取得するところから初めてみました。

Azure AD アプリの構成を設定する

まず、Azure ADからIDトークンを取得するためには、アプリケーションIDが必要です。
そのために、Azure ADへアプリ登録を行う必要があります。

ここでいうアプリとはAzure ADトークンを使用するアプリケーションのことです。
実態としてWebアプリやクライアントアプリがこの時点で必須というわけではありません。

Azure ADにアプリの登録というメニューがあるのでそこから新規登録を行います。

表示名は任意で良いです。
サポートされているアカウントの種類はシングルテナントを選択します。
リダイレクトURIはここでは省略し、後ほど設定します。

作成されるとアプリケーションIDが確認できるようになります。
この画面のアプリケーションIDとテナントIDは後ほどIDトークンを取得する際に使用します。

さて、ここまでの情報でAPIを呼び出すのに必要な情報は揃うのですが、認可フローのオプションなどを設定する必要がいあります。
本日は認可までは行わないのですが、こちらの設定がないとAPI呼び出し時に以下のエラーが発生します。

AADSTS700054: response_type 'id_token' is not enabled for the application

認証->プラットフォーム構成からWebの構成を追加し、適当なリダイレクトURIを設定します。
今回の記事の中ではリダイレクトの処理は実装せず、リダイレクトリクエストを直接解析するので適当な設定値で良いです。
値はhttp://localhost または https:// である必要があります。

認証を行い、トークンを取得する

さて、APIを呼び出す準備が出来たので、実際にトークン取得を行ってみましょう。

Azure ADとの会話はHTTPで行われるため、ブラウザでもcurlでもPostmanでも何でも良いです。
トークン発行フローの兼ね合いでリダイレクトURLが必要になりますが、これもリダイレクトの仕組みを使ってブラウザからアクセスさせているだけなのでブラウザのGoogle Chrome開発ツールなどでリクエストを解析すれば手動でフローを組み立てることが出来ます。

途中、IdP(Azure AD)の認証操作があるので、curlやPostmanだと少しつらいかもしれません。
今回はGoogle Chromeを使いました。

OAuth2とリクエスト内容は似ていますがOIDCでは以下の設定を行います。

  • scopeパラメーターにはopenidを含む
  • response_typeパラメータはid_tokenを設定する
  • nonceパラメータを含む

さらに、この記事はプロファイル情報を取得してみたかったのでscopeprofileを追加しました。
最終的には以下のようなリクエストとなります。

https://login.microsoftonline.com/9b9e2fc6-dc1a-4d7f-97ff-e86600ac5b48/oauth2/v2.0/authorize?client_id=a69a8b7c-236f-4b11-8256-c734a884c2df&response_type=id_token&response_mode=form_post&scope=openid+profile&state=12345&nonce=678910

ではブラウザでリクエストしてみます。

Azure ADへのサインインが要求されました。
対象テナントへのサインインを行います。

アクセス許可の確認がされます。
なお、認証ユーザーが全体管理者ロールを保有している場合、「組織の代理として同意する」のチェックボックスが表示されます。

内容を確認し、承諾を行うと、指定したリダイレクトURIへリダイレクトされます。
このリダイレクト先に、IDトークンが渡される形となります。

Chrome開発者ツールでリダイレクト部分を確認してみます。
Networkタブで指定したFQDNへリクエストが送信されており、フォームデータにid_tokenが設定されていると思います。

id_tokenを解析する

取得されるid_tokenはJSON Web Token(JWT)です。
.を使って3つのパートが結合されており、それぞれ順番にヘッダー、ペイロード、署名で構成されています。
それぞれのパートはBase64URLエンコーディングされています。

ペイロードをデコードしてみましょう。

{
    "aud": "11111111-2222-3333-4444-555555555555",
    "iss": "https://login.microsoftonline.com/11111111-2222-3333-4444-555555555555/v2.0",
    "iat": 1631367964,
    "nbf": 1631367964,
    "exp": 1631371864,
    "aio": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",
    "idp": "https://sts.windows.net/11111111-2222-3333-4444-555555555555/",
    "name": "岩浅 貴大",
    "nonce": "678910",
    "oid": "11111111-2222-3333-4444-555555555555",
    "preferred_username": "iwasa.hoge@mail.com",
    "rh": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "sub": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
    "tid": "11111111-2222-3333-4444-555555555555",
    "uti": "CCCCCCCCCCCCCCCCCC",
    "ver": "2.0"
}

ペイロードのプロフィールに関するクレームが確認出来ました。
期待していた情報が含まれていますね。

iwasa.takahito@hoge hoge % date -r 1631371864
2021年 9月11日 土曜日 23時51分04秒 JST
iwasa.takahito@hoge hoge % date -r 1631367964
2021年 9月11日 土曜日 22時46分04秒 JST

なお、このトークンの有効期間はだいたい1時間ちょっとみたいです。

まとめ

簡単に取得することが出来ました。
id_tokenの中身などはOIDCに準拠した形だと思いますが、アプリ登録・構成設定の流れはAzure AD独自の操作が必要ですので覚えておくとどこかで役に立つかもしれません。

参考