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

Python WebSocket客户端wss连接报403 Forbidden错误问题

问题现象
  • Python客户端基于websocket库连接Azure托管的WebSocket服务,已正确传入认证请求头,使用wss://开头的URL连接时失败,返回错误:
Handshake status 403 Forbidden
  • 完全相同的请求配置在Postman中测试可正常连接
  • 仅当关闭Azure App Service的HTTPSOnly配置项、改用ws://开头的非加密地址发起连接时,Python客户端可正常连通
  • 对比Postman与Python客户端的请求头未发现差异,无法定位403错误根因

出问题的原始代码片段:

def on_message(ws, message):
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws, close_status_code, close_msg):
    print("### closed ###")

def on_open(ws):
    print("Opened connection")

auth_str = "Authorization:Basic abgvrgfrbnfrfurfr"

if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://uri.com/websocket",
                             header=[auth_str],
                              on_open=on_open,
                              on_message=on_message,
                              on_error=on_error,
                              on_close=on_close
                              )
    ws.run_forever(dispatcher=rel) 
    rel.signal(2, rel.abort)  
    rel.dispatch()
根因定位

该问题由两个常见因素叠加导致:

  1. 低版本websocket-client库(<1.0.0)发起wss://加密连接时,默认不会在TLS握手中携带SNI(服务器名称指示)扩展。Azure App Service是多租户托管环境,依赖SNI值匹配对应站点,SNI缺失时请求会被路由到默认空站点,直接返回403。非加密的ws://连接不走TLS握手,不存在该问题。
  2. websocket库发起WebSocket握手时,如果没有显式指定Origin头,会自动生成http://<域名>格式的Origin值。Azure App Service开启HTTPSOnly后会强制校验Origin协议,非HTTPS的Origin会被CORS规则直接拦截返回403;Postman发起请求时默认携带的Origin符合Azure校验规则,因此可以正常连通。
修复方案

按顺序执行以下操作即可解决问题:

  1. 升级websocket-client库到最新版本,修复SNI携带问题:
pip install --upgrade websocket-client
  1. 在WebSocket请求头中显式添加HTTPS协议的Origin头,匹配Azure的CORS校验规则,修正后的初始化代码如下:
if __name__ == "__main__":
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp("wss://uri.com/websocket",
                             header=[
                                 auth_str,
                                 "Origin: https://uri.com"
                             ],
                              on_open=on_open,
                              on_message=on_message,
                              on_error=on_error,
                              on_close=on_close
                              )
    ws.run_forever(dispatcher=rel) 
    rel.signal(2, rel.abort)  
    rel.dispatch()
  1. 如果调整后仍返回403,检查Azure App Service的CORS配置,确认请求Origin在允许列表中,可临时开启"允许所有来源"测试连通性。

补充:如果开启了ARR亲和性(Azure默认开启),首次连接前先发起一次HTTPS GET请求获取站点下发的ARR亲和性Cookie,将Cookie一并加入WebSocket请求头即可避免路由层拦截。

内容的提问来源于stack exchange,提问作者Mr. code

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:01:19