Azure AD OIDCでUserInfoエンドポイントにアクセスする

2021.09.14

いわさです。

先日、Azure ADのIDトークンを取得しました。

OIDCではUserInfo Endpointを使うことでユーザーのクレームへアクセスすることが出来ます。

しかしMicrosoftのドキュメントには以下の記載がありました。

アプリが受信できる ID トークンで利用できる情報は、UserInfo エンドポイントから取得できる情報の上位集合です。 UserInfo エンドポイントを呼び出すトークンを取得すると、同時に ID トークンを取得できます。そのため、ユーザーに関する情報を取得するときは、UserInfo エンドポイントを呼び出す代わりに、その ID トークンを使用することをお勧めします。

代わりに ID トークンを使用する より

要は、IDトークンに必要な情報は含まれているので、UserInfoを呼び出さずにIDトークンの情報を使ってねということです。
しかし何らかの理由でUserInfoを呼び出したいケースがあるかもしれません。

そこで本日はAzure ADを使ってUserInfoエンドポイントを呼び出しました。

UserInfoエンドポイントを探す

UserInfoエンドポイントはopenid-configurationに記載があり、参照してエンドポイントを取得することが可能です。

https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration

{
    "token_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/token",
    "token_endpoint_auth_methods_supported": [
        "client_secret_post",
        "private_key_jwt",
        "client_secret_basic"
    ],
    "jwks_uri": "https://login.microsoftonline.com/common/discovery/v2.0/keys",
    "response_modes_supported": [
        "query",
        "fragment",
        "form_post"
    ],
    "subject_types_supported": [
        "pairwise"
    ],
    "id_token_signing_alg_values_supported": [
        "RS256"
    ],
    "response_types_supported": [
        "code",
        "id_token",
        "code id_token",
        "id_token token"
    ],
    "scopes_supported": [
        "openid",
        "profile",
        "email",
        "offline_access"
    ],
    "issuer": "https://login.microsoftonline.com/{tenantid}/v2.0",
    "request_uri_parameter_supported": false,
    "userinfo_endpoint": "https://graph.microsoft.com/oidc/userinfo",
    "authorization_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/authorize",
    "device_authorization_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/devicecode",
    "http_logout_supported": true,
    "frontchannel_logout_supported": true,
    "end_session_endpoint": "https://login.microsoftonline.com/common/oauth2/v2.0/logout",
    "claims_supported": [
        "sub",
        "iss",
        "cloud_instance_name",
        "cloud_instance_host_name",
        "cloud_graph_host_name",
        "msgraph_host",
        "aud",
        "exp",
        "iat",
        "auth_time",
        "acr",
        "nonce",
        "preferred_username",
        "name",
        "tid",
        "ver",
        "at_hash",
        "c_hash",
        "email"
    ],
    "kerberos_endpoint": "https://login.microsoftonline.com/common/kerberos",
    "tenant_region_scope": null,
    "cloud_instance_name": "microsoftonline.com",
    "cloud_graph_host_name": "graph.windows.net",
    "msgraph_host": "graph.microsoft.com",
    "rbac_url": "https://pas.windows.net"
}

アクセストークンを取得する

https://graph.microsoft.com/oidc/userinfoはアクセストークンを取得し、ベアラートークンとしてセットすることで情報を取得することが出来ます。

先日の記事に取得・検証したものはIDトークンです。
今の認可フロー設定の場合は以下の設定をした上で次のURLでアクセスすることでアクセストークンを取得することが出来ます。

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

無事アクセストークンが取得されていますね。

なお、Azureポータル上の認証メニューで上記を設定していない場合はレスポンスタイプのunsupportedエラーが発生します。

error: unsupported_response_type
error_description: AADSTS700051: response_type 'token' is not enabled for the application.

エンドポイントにアクセスする

さて、アクセストークンが取得出来たので、GraphAPIを呼び出してみます。

今回はPostmanを使ってみました。

Authタグでタイプにベアラートークンを選択し、先程取得したアクセストークンを貼り付けます。
メソッドはGETでもPOSTでもいけますう。

取得出来ました。

まとめ

IDトークン取得する流れと同じですね。
ユーザー操作で認証を行ったのちにコールバックURLへリダイレクトされてトークンを取得。それを使ってAPIへアクセスするという流れです。

コードを使う場合だとまた少し違うフローになるようなのですが、それはまた今度試してみたいと思います。

参考