使用Zeep配合HTTPBasicAuth调用SOAP方法返回401错误该如何解决?
问题排查与解决方案
核心原因
你当前配置的是HTTP传输层的Basic认证,而绝大多数SOAP类型的Web Service要求认证信息遵循WS-Security规范,内嵌到SOAP信封的Header字段中,HTTP层的认证信息不会被服务端识别,因此返回401未授权错误。
解决方案
方案1:添加WS-Security用户名令牌认证(优先尝试,适配90%以上的SOAP服务场景)
无需在requests会话中配置HTTPBasicAuth,改为在Zeep客户端中指定WSSE认证参数,代码示例如下:
from requests import Session from zeep import Client from zeep.transports import Transport from zeep.wsse.username import UsernameToken session = Session() # 去掉原有的session.auth配置,改用wsse参数 client = Client( 'http://my-endpoint.com/production.svc?wsdl', transport=Transport(session=session), wsse=UsernameToken(user, password) ) Items = client.get_type('ns1:ItemsType') response = client.service.publishService('MyProps', Items ={ 'ItemInformation': { '':'' } })
方案2:强制预发送HTTP Basic认证头
如果确认服务端仅支持HTTP层Basic认证,可能是服务端未实现401认证挑战逻辑,默认不会主动返回要求认证的响应,requests默认等待401挑战后才发送认证头就会触发401。可直接手动构造认证头添加到会话中:
from requests import Session from base64 import b64encode from zeep import Client from zeep.transports import Transport session = Session() # 手动构造Basic认证头,强制所有请求携带 auth_cred = f"{user}:{password}".encode('utf-8') auth_b64 = b64encode(auth_cred).decode('utf-8') session.headers['Authorization'] = f'Basic {auth_b64}' client = Client('http://my-endpoint.com/production.svc?wsdl', transport=Transport(session=session)) # 后续业务逻辑不变
可选适配调整
如果以上方案仍报错,可根据SOAP UI的请求配置补充以下参数:
- 若服务端使用SOAP 1.2协议,在创建Transport对象时指定版本:
Transport(session=session, soap_version='1.2') - 开启调试日志对比请求差异:
把打印出的请求头、SOAP内容和SOAP UI的成功请求对比,即可快速定位剩余差异点。import logging logging.basicConfig(level=logging.DEBUG) logging.getLogger('zeep.transports').setLevel(logging.DEBUG)
内容的提问来源于stack exchange,提问作者James Windshield
相关产品推荐
相关产品推荐

