python - 连接到 Azure AD 时如何创建客户端断言 JWT 令牌?
问题描述
我的问题是,在将授权代码发送回 Azure AD 以获取访问令牌时,我不确定使用什么来签署 JWT 令牌以进行客户端断言。支持的身份验证方法是“private_key_jwt”。唯一提供的是 client_id、tenant_id 和清单文件端点。
解决方案
要完成整个过程,我们应该首先创建证书。我在这里使用自签名证书进行演示。
第 1 步:创建 .cer 和 .key 文件,我们将上传 .cer 到 Azure AD 应用程序并使用 .key 文件签署我们的 JWT 令牌。
1)通过Powershell创建一个密码为123456的自签名证书:
$cert = New-SelfSignedCertificate -certstorelocation cert:\localmachine\my -dnsname stantest.com
$pwd = ConvertTo-SecureString -String '123456' -Force -AsPlainText
$path = 'cert:\localMachine\my\' + $cert.thumbprint
Export-PfxCertificate -cert $path -FilePath <path of your pfx file> -Password $pwd
2)基于CMD中的 .pfx 文件创建 .cer 文件:
openssl pkcs12 -in <path of .pfx file> -clcerts -nokeys -out <path of .cer>
3)在CMD中基于 .pfx 文件创建 .key 文件:
openssl pkcs12 -in <path of .pfx file> -nocerts -nodes -out <path of .pem file>
openssl rsa -in <path of .pem file> -out <path of .key file>
第 2步:将 .cer 文件上传到您的 Azure AD 应用并记下其指纹值:
第 3 步:使用下面的 python 代码签署 JWT 并为 Microsoft Graph API 交换访问令牌(确保您的应用已被授予列出用户的权限):
import sys
import json
import logging
import requests
import msal
config = {
"client_id":"your application ID here",
"authority":"https://login.microsoftonline.com/Your tenant name or ID",
"thumbprint":"cert thumbprint value in step2",
"private_key_file":r"the path of .pem file of private key",
"scope": ["https://graph.microsoft.com/.default"],
"endpoint":"https://graph.microsoft.com/v1.0/users?$top=1"
}
app = msal.ConfidentialClientApplication(
config["client_id"], authority=config["authority"],
client_credential={"thumbprint": config["thumbprint"], "private_key": open(config['private_key_file']).read()},
)
result = app.acquire_token_for_client(scopes=config["scope"])
if "access_token" in result:
print("Access Token value: " + result['access_token']);
# Calling graph using the access token
graph_data = requests.get( # Use token to call downstream service
config["endpoint"],
headers={'Authorization': 'Bearer ' + result['access_token']},).json()
print("Graph API call result: %s" % json.dumps(graph_data, indent=2))
else:
print(result.get("error"))
print(result.get("error_description"))
print(result.get("correlation_id")) # You may need this when reporting a bug
推荐阅读
- typescript - 尝试按键访问值时,打字稿字典对象返回未定义
- opencv - Opencv找到所有最小最大点
- python - 在带有 python 列表的 sql 查询中使用 isin
- mongodb - Mongodb聚合查询计算2点之间的距离
- r - Timevis - 使不同的盒子有颜色取决于不同组中的名称
- spring-boot - Redis 读取超时异常
- ios - Swift IOS:从通知打开应用程序时调用 UIviewController 的特定功能
- ruby - Gemfile 中 Ruby 版本的悲观 Ruby 运算符导致错误
- apache-spark - how spark distribute training tasks to evenly across executors?
- r - IF...ELSE 在 R 帮助中