Azure DevOps流水线调用REST API下载NPM制品遇401错误求助
问题描述
在Azure DevOps流水线中尝试通过Python调用REST API下载NPM制品,代码如下:
opener = urllib.request.build_opener() opener.addheaders = [('Authorization', 'Bearer ' + "$(System.AccessToken)")] urllib.request.install_opener(opener) url = f"https://pkgs.dev.azure.com/{organization}/{project}/_apis/packaging/feeds/{feedId}/npm/packages/{packageName}/versions/{packageVersion}/content?api-version=7.1-preview.1" urllib.request.urlretrieve(url, target)
$(System.AccessToken)令牌可正常用于其他API调用(如下载流水线制品、读取feed属性),但执行上述代码返回401未授权错误。- 将URL粘贴到已登录的浏览器中可正常下载,说明URL格式无误。
- 尝试通过创建
.npmrc文件和vsts-npm-auth获取其他令牌,仍出现相同错误。
解决思路
1. 检查System.AccessToken的权限范围
System.AccessToken的默认权限可能不足以访问NPM包内容,需调整流水线作业权限:
- 编辑流水线,找到对应作业,点击「更多选项」→「权限」。
- 确保「包装(Packaging)」权限设置为「允许」,重点确认「读取」权限已开启。
- 如果是项目级feed,需验证流水线服务账户(
[项目名] Build Service ([组织名]))在feed的权限列表中拥有「读者」或更高权限。
2. 修正请求头配置
- 确认
Bearer与令牌之间的空格存在(代码写法正确,但可打印令牌前几位验证是否被正确注入,注意不要泄露完整令牌)。 - 添加
Accept请求头指定内容类型,避免服务端返回格式不兼容:opener.addheaders = [ ('Authorization', 'Bearer ' + "$(System.AccessToken)"), ('Accept', 'application/octet-stream') ]
3. 改用Azure DevOps Python SDK
SDK已封装权限处理逻辑,稳定性更高:
- 安装依赖:
pip install azure-devops - 示例代码:
from azure.devops.connection import Connection from msrest.authentication import BasicAuthentication organization_url = f"https://dev.azure.com/{organization}" token = "$(System.AccessToken)" credentials = BasicAuthentication('', token) connection = Connection(base_url=organization_url, creds=credentials) packaging_client = connection.clients.get_packaging_client() package_content = packaging_client.get_package_content( feed_id=feedId, package_name=packageName, package_version=packageVersion, project=project ) with open(target, 'wb') as f: f.write(package_content.content)
4. 检查Feed可见性与成员权限
- 若为组织级feed,确认流水线所在项目已加入feed的「可见项目」列表。
- 若为专用feed,需确保流水线服务账户被添加为feed成员或授予访问权限。
5. 排查vsts-npm-auth配置
- 确保
.npmrc的registry URL格式正确:registry=https://pkgs.dev.azure.com/{organization}/{project}/_packaging/{feedId}/npm/registry/ - 流水线环境中执行
vsts-npm-auth需添加非交互参数:vsts-npm-auth -config .npmrc -nonInteractive -force
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

