LoginSignup
2
1

PythonでAzure ADのIDトークンを検証する

Last updated at Posted at 2023-09-08

はじめに

案件でAzure ADが発行するIDトークンの検証をしたい・・・!となりましたが、全く見当もつかず困りました。
そんな時、社内の方に検証方法を教えていただき実現できたので、備忘も兼ねて共有させてください。

結論

Microsoftが提供している公開鍵を使用してIDトークンの検証が可能です。
https://login.microsoftonline.com/common/v2.0/.well-known/openid-configurationにアクセスすると公開鍵を取得できるURLがjwks_uriに記載してあり、このURLから公開鍵をJSONで取得可能です。

  • 公開鍵は24時間で更新されるため、一度ダウンロードして恒久的に使用することは不可なのでご注意ください。
  • IDトークンはv1.0v2.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リクエスト送信に使用、PyJWTcryptographyはIDトークンの検証に使用します。

ソースコード

main.py
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トークンの検証を実施します。

  1. Microsoft提供のURLにHTTPリクエストを送信し、公開鍵の一覧を取得
  2. 公開鍵の一覧からIDトークンとkidが一致する公開鍵を抽出
  3. IDトークンを検証し、有効かチェック(引数audienceはAzure ADのクライアントIDを指定)

検証に失敗した場合、InvalidTokenErrorが発生するためtry-except句で検知可能です。

Azure ADのクライアントIDは使用するADアプリの下記項目をコピーしてください。

image.png

動作確認

作成した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トークン検証方法を紹介させていただきました!必要に応じて活用いただけますと幸いです。最後までご覧いただきありがとうございました!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1