携带Access Token调用Azure API端点返回401 Unauthorized(缺失声明)
Azure API调用返回401 missing_claim错误排查
我们有一段Python代码用于调用部署在Microsoft Azure上的API,代码通过azure-identity库获取Access Token,再将Token放入Authorization请求头中。尽管获取到的Token在jwt.io验证签名有效,但调用API端点时仍返回401错误,提示missing_claim。我们已确认API权限配置正确,尝试过msal库也遇到相同问题,寻求错误原因及解决方法。
使用azure-identity的调用代码
import requests from azure.identity import ClientSecretCredential TENANT_ID = 'my-tenant-id' CLIENT_ID = 'my-client-id' CLIENT_SECRET = "my_client-secret" SCOPES = ['api://my-client-id/.default'] identity_client = ClientSecretCredential(tenant_id=TENANT_ID, client_id=CLIENT_ID, client_secret=CLIENT_SECRET, authority='https://login.microsoftonline.com') access_token = identity_client.get_token(SCOPES[0]) #Request the API endpoint json = { "function_name": "function_name", "param1": "param1_value", "param2": "param2_value", } headers = { "Authorization": f"Bearer {access_token.token}", "Content-Type": "application/json" } response = requests.get('https://myapi.whatever/myendpoint', json=json, headers=headers) if response.status_code == 200: print(response.json()["result"]) else: print(response)
错误响应
{'_content': b'missing_claim', '_content_consumed': True, '_next': None, 'status_code': 401, 'headers': {'Date': 'Fri, 12 May 2023 15:25:27 GMT', 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Request-Context': 'appId=cid-v1:752b04bc-08aa-4002-a618-d3e7be07a371', 'Strict-Transport-Security': 'max-age=31536000 ; includeSubDomains', 'X-XSS-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'X-Frame-Options': 'sameorigin', 'X-Permitted-Cross-Domain-Policies': 'none', 'Referrer-Policy': 'no-referrer'}, 'raw': <urllib3.response.HTTPResponse at 0x2967109e3a0>, 'url': 'https://myapi.whatever/myendpoint', 'encoding': 'ISO-8859-1', 'history': [], 'reason': 'Unauthorized', 'cookies': <RequestsCookieJar[]>, 'elapsed': datetime.timedelta(microseconds=306335), 'request': <PreparedRequest [GET]>, 'connection': <requests.adapters.HTTPAdapter at 0x296710856a0>}
尝试过的msal库代码
app = msal.ConfidentialClientApplication( client_id=CLIENT_ID, client_credential=[CLIENT_SECRET], authority='https://login.microsoftonline.com/my-tenant-id', token_cache=cache, ) result = None result = app.acquire_token_silent(scopes=SCOPES, account=None) if not result: print('Here') result = app.acquire_token_for_client(scopes=SCOPES)
可能的原因及解决方法
- Scope配置错误:
确保SCOPES中的API标识符是目标API的应用ID URI或客户端ID,而非调用方应用的CLIENT_ID。例如目标API的应用ID URI为api://my-api-resource-id,则Scope应设为api://my-api-resource-id/.default。 - Token受众声明不匹配:
在jwt.io解析Token,检查aud声明是否严格匹配目标API的应用ID URI或客户端ID。API会验证Token是否是发给自己的,不匹配则会返回权限错误。 - 缺少权限声明:
确认调用应用已被授予目标API的对应权限(应用权限需管理员同意),并检查Token中是否包含roles(应用权限)或scp(委托权限)声明,API可能要求特定权限声明才允许访问。 - 请求方法问题:
代码中使用requests.get但传递了json参数,GET请求通常不携带请求体,部分API可能无法正确处理这种情况,进而触发验证逻辑异常。建议改为requests.post,或把参数放在URL查询字符串中。 - Authority配置不完整:
在ClientSecretCredential中,authority应显式包含租户ID,即https://login.microsoftonline.com/{TENANT_ID},避免SDK自动补全可能带来的问题。
内容的提问来源于stack exchange,提问作者Aniss Chohra
相关产品推荐
相关产品推荐

