はじめに
案件でAzure ADが発行するIDトークンの検証をしたい・・・!となりましたが、全く見当もつかず困りました。
そんな時、社内の方に検証方法を教えていただき実現できたので、備忘も兼ねて共有させてください。
結論
Microsoftが提供している公開鍵を使用してIDトークンの検証が可能です。
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configurationにアクセスすると公開鍵を取得できるURLがjwks_uri
に記載してあり、このURLから公開鍵をJSONで取得可能です。
- 公開鍵は24時間で更新されるため、一度ダウンロードして恒久的に使用することは不可なのでご注意ください。
- IDトークンは
v1.0
とv2.0
の2種類バージョンが存在し、公開鍵のURLも異なりますので、検証したいIDトークンのバージョンに応じて使用するURLを判断してください。(今回はv2.0
を使用)
参考URL:https://learn.microsoft.com/ja-jp/azure/active-directory/develop/access-tokens#validate-tokens
使用した環境
- Python・・・
3.9
- PyJWT・・・
2.8.0
- requests・・・
2.31.0
- cryptography・・・
41.0.3
実装
ライブラリ
必要なライブラリをインストールします。
pip install requests pyjwt cryptography
requests
は公開鍵を取得するHTTPリクエスト送信に使用、PyJWT
、cryptography
はIDトークンの検証に使用します。
ソースコード
import jwt
import requests
from jwt.algorithms import RSAAlgorithm
# 検証したいIDトークン
token = "XXX"
# Azure ADのクライアントID
client_id = "XXX"
# 1.公開鍵の一覧を取得
key_url = requests.get("https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration").json()["jwks_uri"]
keys = requests.get(key_url).json()["keys"]
# 2.IDトークンの署名を検証する公開鍵を抽出
header = jwt.get_unverified_header(token)
for key in keys:
# kidが一致している公開鍵を抽出
if key["kid"] == header["kid"]:
public_key = jwt.algorithms.RSAAlgorithm.from_jwk(key)
break
try:
# 3.IDトークンを検証
decoded_token = jwt.decode(
token,
public_key,
audience=client_id,
algorithms=["RS256"]
)
print("有効なIDトークンです")
# 検証に失敗した場合
except jwt.exceptions.InvalidTokenError as e:
print("不正なIDトークンです")
print(f"Error詳細:{e}")
下記流れでIDトークンの検証を実施します。
- Microsoft提供のURLにHTTPリクエストを送信し、公開鍵の一覧を取得
- 公開鍵の一覧からIDトークンと
kid
が一致する公開鍵を抽出 - IDトークンを検証し、有効かチェック(引数
audience
はAzure ADのクライアントIDを指定)
検証に失敗した場合、InvalidTokenError
が発生するためtry-except
句で検知可能です。
動作確認
作成したmain.py
を実行して有効、不正なIDトークンを検証できるかそれぞれ確認してみましょう!
有効なIDトークン
python main.py
有効なIDトークンです
不正なIDトークン
改ざんしたIDトークン
python main.py
不正なIDトークンです
Error詳細:Signature verification failed
有効期限が切れたIDトークン
python main.py
不正なIDトークンです
Error詳細:Signature has expired
それぞれ適切に検証されていますね!
不正な場合は署名の改ざんだけではなく、有効期限切れも検知可能です。
Azure ADが発行するIDトークンの有効期限は1時間です。
参考URL:https://learn.microsoft.com/ja-jp/azure/active-directory/develop/id-tokens
おわりに
Azure ADのIDトークン検証方法を紹介させていただきました!必要に応じて活用いただけますと幸いです。最後までご覧いただきありがとうございました!