You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Apache代理后Jira REST API调用异常:Python报401但curl正常

解决Apache反向代理后Jira REST API双认证401问题

我完全理解你的困惑——curl能正常返回结果,但Python代码却一直报401,核心原因是curl允许发送多个相同的HTTP头字段,而Python的requests库(包括依赖它的python-jira)默认会覆盖重复的头字段。

你的curl命令同时发送了两个Authorization头:一个来自-u jirauser:jirapass(给Jira的认证),另一个是你手动添加的(给Apache代理的认证)。但在Python代码中,auth参数(或python-jira的basic_auth)会自动生成并覆盖你手动添加的Authorization头,导致请求只携带了Jira的认证信息,缺少Apache代理要求的认证,从而返回401 Unauthorized。

下面是两种可行的解决方案:

方案1:使用requests库手动构造双认证头

因为requests的字典式headers会覆盖重复键,所以我们需要用元组列表来定义headers,这样就能发送多个相同的Authorization头,和curl的行为一致:

import requests
import base64

# 配置代理(Apache)和Jira的认证信息
proxy_user = "proxyuser"
proxy_pass = "proxypass"
jira_user = "jirauser"
jira_pass = "jirapass"

# 生成Base64编码的认证字符串
proxy_auth = base64.b64encode(f"{proxy_user}:{proxy_pass}".encode('utf-8')).decode('utf-8')
jira_auth = base64.b64encode(f"{jira_user}:{jira_pass}".encode('utf-8')).decode('utf-8')

# 用元组列表定义headers,支持重复的Authorization字段
headers = [
    ('Content-Type', 'application/json'),
    ('Authorization', f'Basic {proxy_auth}'),  # Apache代理认证
    ('Authorization', f'Basic {jira_auth}')     # Jira认证
]

# 发送请求
url = "http://127.0.0.1/jira/rest/api/2/search?jql=key=DEV4"
response = requests.get(url, headers=headers)

# 验证结果
print(f"响应状态码:{response.status_code}")
if response.ok:
    print("返回数据:", response.json())
else:
    print("错误信息:", response.text)

方案2:适配python-jira库发送双认证头

python-jira内部依赖requests,我们可以通过自定义requests Session来注入双认证头,避免basic_auth参数覆盖我们的头配置:

from jira import JIRA, JIRAError
import requests
import base64
import sys

# 配置认证信息
proxy_user = "proxyuser"
proxy_pass = "proxypass"
jira_user = "Jira_username"
jira_pass = "Jira_password"

# 生成Base64编码的认证字符串
proxy_auth = base64.b64encode(f"{proxy_user}:{proxy_pass}".encode('utf-8')).decode('utf-8')
jira_auth = base64.b64encode(f"{jira_user}:{jira_pass}".encode('utf-8')).decode('utf-8')

# 创建自定义的requests Session,注入双认证头
session = requests.Session()
session.headers.update([
    ('X-Atlassian-Token', 'no-check'),
    ('Cache-Control', 'no-cache'),
    ('Content-Type', 'application/json'),
    ('Authorization', f'Basic {proxy_auth}'),
    ('Authorization', f'Basic {jira_auth}')
])

# 初始化JIRA客户端,使用自定义Session
jira_options = {
    'server': 'http://127.0.0.1/jira',
    'verify': True
}

try:
    jira = JIRA(
        options=jira_options,
        session=session,  # 传入自定义Session
        validate=True
    )
    # 测试连接:获取项目列表
    projects = jira.projects()
    print(f"成功连接Jira!共获取到{len(projects)}个项目")
except JIRAError as e:
    print(f"初始化Jira连接失败,错误信息:[{e}]")
    sys.exit()

额外建议:更规范的代理认证方式

如果可以修改Apache配置,建议将代理的认证改为使用Proxy-Authorization头(而非和Jira共用Authorization),这样就不会出现头字段冲突的问题。此时Python代码可以更清晰地分离两种认证:

  • 用auth参数设置Jira的Authorization头
  • 在headers中添加Proxy-Authorization: Basic ...用于Apache代理认证

这种方式更符合HTTP标准,也能避免后续的头字段覆盖问题。

内容的提问来源于stack exchange,提问作者A. Lein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:00:23