我需要实现一个脚本来检查我从前端收到的天蓝色令牌是否是真实的令牌。由于我正在等待前端开发人员实现 SAP(单一应用程序应用程序),因此我实施了一个简单的脚本来生成令牌:
import requests
client_id = "MY_CLIENT_ID"
tenant_id = "MY_TENANT_ID"
client_secret = "MY_CLIENT_SECRET"
username = "mail"
password = "password"
scope = "https://graph.microsoft.com/.default"
token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
data = {
"grant_type": "password",
"client_id": client_id,
"client_secret": client_secret,
"scope": scope,
"username": username,
"password": password,
}
# Request
response = requests.post(token_url, data=data)
if response.status_code == 200:
token_response = response.json()
access_token = token_response.get("access_token")
print("Access Token:", access_token)
# UserInfo
user_info_url = "https://graph.microsoft.com/v1.0/me"
headers = {"Authorization": f"Bearer {access_token}"}
user_response = requests.get(user_info_url, headers=headers)
if user_response.status_code == 200:
user_info = user_response.json()
print("Informazioni utente:")
print(user_info)
else:
print("User error:")
print(user_response.status_code, user_response.text)
else:
print("Error")
print(response.status_code, response.text)
通过上面的脚本我能够获得访问令牌。
现在,所爱的脚本应该检查令牌是否真实:
import msal
import json
# Configuration
CLIENT_ID = "SAME_CLIENT_ID"
CLIENT_SECRET = "SAME_SECRET"
TENANT_ID = "SAME_TENANT_ID"
RESOURCE = "api://graph.microsoft.com"
# Token Verification Function
def verify_token(access_token):
try:
# Initialize MSAL ConfidentialClientApplication
app = msal.ConfidentialClientApplication(
client_id=CLIENT_ID,
client_credential=CLIENT_SECRET,
authority=f"https://login.microsoftonline.com/{TENANT_ID}"
)
# Acquire a token on behalf of the user to validate the existing token
result = app.acquire_token_on_behalf_of(
user_assertion=access_token,
scopes=[f"{RESOURCE}/.default"]
)
if "access_token" in result:
print("Token is valid.")
print("Token claims:", json.dumps(result.get("id_token_claims"), indent=2))
return True
else:
print("Token validation failed:", result.get("error_description"))
return False
except Exception as e:
print("An error occurred while verifying the token:", str(e))
return False
token_to_validate = input("Enter the token to validate: ")
# Verify the token
is_valid = verify_token(token_to_validate)
if is_valid:
print("The token is authentic.")
else:
print("The token is not authentic.")
在输出中我有这样的消息:
Token validation failed: AADSTS50013: Assertion failed signature validation.
[Reason - Key was found, but use of the key to verify the signature failed., Thumbprint of key used by client: 'IDED_BY_ME',
Found key 'Start=11/27/2024 09:04:39, End=11/27/2029 09:04:39',
Please visit the Azure Portal, Graph Explorer or directly use MS Graph to see configured keys for
app Id '00000000-0000-0000-0000-000000000000'.
Review the documentation at https://docs.microsoft.com/en-us/graph/deployments
to determine the corresponding service endpoint
and https://docs.microsoft.com/en-us/graph/api/application-get?view=graph-rest-1.0&tabs=http to build a query request URL,
such as 'https://graph.microsoft.com/beta/applications/00000000-0000-0000-0000-000000000000'].
Trace ID: 01e09def-59ad-49a3-addc-721fdbc67000
Correlation ID: 84b76158-1dc7-4932-88de-50bae5f8ac36 Timestamp: 2025-01-17 12:18:30Z
The token is not authentic.
我不明白错误在哪里,因为我提供了刚刚创建的令牌。我已经验证该功能正在 https://jwt.ms/ 上运行,并且我正在按照链接的建议进行操作。
在天蓝色上我有范围User.Read
有什么建议吗?
最初,我注册了单租户 Microsoft Entra ID 应用程序:
生成访问令牌后,当我使用
scope: https://graph.microsoft.com/.default
运行您提到的代码时,我得到了相同的令牌验证错误响应:
同意@junnas,您为应用程序提供的范围,需要使用您的应用程序定义的范围来请求令牌
注意:Microsoft Graph API 令牌不用于验证,
aud: https://graph.microsoft.com
,因为它不用于应用程序验证,用于获取 Microsoft Graph API 访问权限
要解决该错误,您需要避免
https://graph.microsoft.com/.default
使用 Microsoft Graph API 验证访问令牌的范围。您必须公开应用程序的 API,并使用您自己的应用程序和自定义 API 来验证访问令牌。
添加了应用程序 ID URI,并公开了如下 API:
向您的自定义 API 添加并授予权限,如下所示:
暴露 API 后,我为应用程序生成了客户端密钥:
我修改了脚本,将访问 Microsoft Graph API 的范围更改为自定义 API。
api://<application-id>/User.Read
使用以下修改后的脚本:
client_id = "<client-id>"
tenant_id = "<tenant-id>"
client_secret = "<client-secret>"
username = "username"
password = "password"
scope = "api://<application-id>/User.Read"
token_url = f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token"
data = {
"grant_type": "password",
"client_id": client_id,
"client_secret": client_secret,
"scope": scope,
"username": username,
"password": password,
}
# Request
response = requests.post(token_url, data=data)
if response.status_code == 200:
token_response = response.json()
access_token = token_response.get("access_token")
print("Access Token:", access_token)
# UserInfo
user_info_url = "https://graph.microsoft.com/v1.0/me"
headers = {"Authorization": f"Bearer {access_token}"}
user_response = requests.get(user_info_url, headers=headers)
if user_response.status_code == 200:
user_info = user_response.json()
print("Informazioni utente:")
print(user_info)
else:
print("User error:")
print(user_response.status_code, user_response.text)
else:
print("Error")
print(response.status_code, response.text)
import msal
import json
# Configuration
CLIENT_ID = "<client-id>"
CLIENT_SECRET = "<client-secret>"
TENANT_ID = "<tenant-id>"
RESOURCE = "api://<application-id>"
# Token Verification Function
def verify_token(access_token):
try:
# Initialize MSAL ConfidentialClientApplication
app = msal.ConfidentialClientApplication(
client_id=CLIENT_ID,
client_credential=CLIENT_SECRET,
authority=f"https://login.microsoftonline.com/{TENANT_ID}"
)
# Acquire a token on behalf of the user to validate the existing token
result = app.acquire_token_on_behalf_of(
user_assertion=access_token,
scopes=[f"{RESOURCE}/.default"]
)
if "access_token" in result:
print("Token is valid.")
print("Token claims:", json.dumps(result.get("id_token_claims"), indent=2))
return True
else:
print("Token validation failed:", result.get("error_description"))
return False
except Exception as e:
print("An error occurred while verifying the token:", str(e))
return False
token_to_validate = input("Enter the token to validate: ")
# Verify the token
is_valid = verify_token(token_to_validate)
if is_valid:
print("The token is authentic.")
else:
print("The token is not authentic.")
.
回应:
此外,通过解码访问令牌来验证 https://jwt.io 上的令牌:
如果问题仍然存在,请在应用程序注册上创建新应用程序并尝试相同的操作。
参考:
吉尔伯特SO Thread 由我。
令牌生成的范围与您验证的范围不同。这很可能是问题所在。
查看@juunas 的评论。