Azure 访问令牌刚刚创建,但无法验证其真实性

问题描述 投票:0回答:2

我需要实现一个脚本来检查我从前端收到的天蓝色令牌是否是真实的令牌。由于我正在等待前端开发人员实现 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

有什么建议吗?

python azure jwt token
2个回答
0
投票

最初,我注册了单租户 Microsoft Entra ID 应用程序:

enter image description here

生成访问令牌后,当我使用

scope: https://graph.microsoft.com/.default
运行您提到的代码时,我得到了相同的令牌验证错误响应:

enter image description here

enter image description here

同意@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:

enter image description here

向您的自定义 API 添加并授予权限,如下所示:

enter image description here

暴露 API 后,我为应用程序生成了客户端密钥:

enter image description here

我修改了脚本,将访问 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.")

.

回应:

enter image description here

此外,通过解码访问令牌来验证 https://jwt.io 上的令牌:

enter image description here

enter image description here

如果问题仍然存在,请在应用程序注册上创建新应用程序并尝试相同的操作。

参考:

吉尔伯特

SO 主题

SO Thread 由我。


0
投票

令牌生成的范围与您验证的范围不同。这很可能是问题所在。

查看@juunas 的评论。

© www.soinside.com 2019 - 2024. All rights reserved.