使用Python调用Azure DevOps Pipeline时遇203错误(Bearer Token无效)
问题排查与解决
1. 资源标识(Resource)配置错误
获取Azure AD令牌时,resource参数必须指定Azure DevOps的官方资源URI:https://dev.azure.com/,原代码里写的499b84ac-1321-427f-aa17-267ca6975798/.default是错误的,这会导致拿到的令牌无法被Azure DevOps识别,直接返回203要求登录。
修改为:
resource = "https://dev.azure.com/"
2. 请求体格式错误
调用Azure DevOps API时,requests.post用data=body会以表单格式发送请求,但AzDo API要求JSON格式的请求体。有两种修正方式:
- 改用
json=body参数,让requests自动序列化并匹配Content-Type:r = requests.post(uri, headers=azdevheaders, json=body) - 或者手动将body转为JSON字符串后传递:
r = requests.post(uri, headers=azdevheaders, data=json.dumps(body))
3. 代码缩进错误
原代码中if name == "choice1"及后续逻辑不在HttpTrigger函数内部,会触发变量作用域错误(外部无法访问函数内的name变量)。必须把这部分代码缩进,放到函数定义范围内:
修正后的完整函数示例:
import datetime import logging import azure.functions as func import os import requests import json app = func.FunctionApp() @app.route(route="HttpTrigger", auth_level=func.AuthLevel.FUNCTION) def HttpTrigger(req: func.HttpRequest) -> func.HttpResponse: logging.info('Python HTTP trigger function processed a request.') resource = "https://dev.azure.com/" endpoint = os.environ['IDENTITY_ENDPOINT'] header = os.environ['IDENTITY_HEADER'] headers = { 'X-Identity-Header': header } user_managed_identity_id = "&mi_res_id=my UMI resource ID" url = f"{endpoint}?api-version=2019-08-01&resource={resource}" + user_managed_identity_id name = req.params.get('name') if name == "choice1": resp = requests.get(url, headers=headers) token = resp.json() token = token.get('access_token') azdevheaders = { "Content-Type": "application/json", "Authorization": f"Bearer {token}" } body = { "templateParameters": {} } uri = "https://dev.azure.com/<my org>/<my project>/_apis/pipelines/7/runs?api-version=7.0" cusname = req.params.get('cusname') r = requests.post(uri, headers=azdevheaders, json=body) return func.HttpResponse(f"Hello, {cusname}. This HTTP triggered function executed successfully, AzDo response code: {r.status_code}") elif name == "choice2": cusname = req.params.get('cusname') return func.HttpResponse(f"Hello, {cusname}. This HTTP triggered function executed successfully. {name}") else: return func.HttpResponse( "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.", status_code=200 )
4. 托管身份权限验证
确认你的用户托管身份(UMI)在Azure DevOps项目中拥有队列构建权限:
- 进入Azure DevOps项目设置 → 权限 → 先将UMI添加为项目用户
- 给该身份授予“队列构建”的允许权限
内容的提问来源于stack exchange,提问作者Matt Baylis
相关产品推荐
相关产品推荐

