からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

Azure AD アプリケーションの accessTokenAcceptedVersion を指定したときの JWT の aud の挙動について

Azure AD アプリケーションのアクセス トークンの中身について accessTokenAcceptedVersion を指定したときの JWT の aud の挙動に違いがあったのでメモです。

前提条件

サーバーとなる Azure AD アプリケーションを登録します。アプリケーション ID URL を「api://{{appid}}」のように作成して適当にスコープを追加します。

f:id:karamem0:20210730211844p:plain

この Azure AD アプリケーションへにアクセスするためのクライアントになる Azure AD アプリケーションを登録します。[API のアクセス許可] でサーバーのアプリケーションへのアクセス許可を追加します。

f:id:karamem0:20210730212242p:plain

これで準備は完了です。以下のようにリクエストを投げるとトークンを取得することができます。*1 scope に アプリケーション ID URL を指定するのがポイントです。

POST /6c4c0561-a8bb-4706-9cc9-3ba9b66aca3d/oauth2/v2.0/token
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

grant_type=password
&scope=api://fef0e665-3890-4797-bfe5-658589da1adb/.default
&client_id=a95306e4-14f1-4389-b0f5-24feb7f3c744
&client_secret=pFy5...
&username=someone@example.com
&password=Fzsr...

検証結果

まずは accessTokenAcceptedVersion が 1 または null の場合です。docs には null の場合は 1 になると書いてあるので同じと考えていいでしょう。

docs.microsoft.com

取得したトークンをデコードします。aud にはアプリケーション ID URL が入っているのがわかります。

{
  "aud": "api://fef0e665-3890-4797-bfe5-658589da1adb",
  "iss": "https://sts.windows.net/6c4c0561-a8bb-4706-9cc9-3ba9b66aca3d/",
  ...
  "ver": "1.0"
}

次に accessTokenAcceptedVersion を 2 にしてトークンを取得します。scope にアプリケーション ID URL を指定しているのですが、aud にはアプリケーション ID が入ります。

{
  "aud": "fef0e665-3890-4797-bfe5-658589da1adb",
  "iss": "https://login.microsoftonline.com/6c4c0561-a8bb-4706-9cc9-3ba9b66aca3d/v2.0",
  ...
  "ver": "2.0"
}

まとめ

何が困るかというと Azure Web App を作って自前で (Easy Auth じゃなくて) Azure AD 認証を適用したときに aud の値を検証するのですが、これが違って入ってくると割と困るんですよね。アプリケーション ID URL がくると思ってたらアプリケーション ID がくるので認証が通らなくてなんでだと悩むという。というか悩みました。いまのところ、一部を除きどちらのバージョンでも特に問題なさそうなので、特別な理由がなければ既定値の null のままでいい気がします。

*1:見やすさのために改行しています。