是否有支持修改初始请求或自定义http.Client的Golang WebSocket库
gorilla/websocket适配Kerberos认证的可行解决思路
你之前的方案失效的核心原因:单独发送的带认证GET请求和WebSocket握手请求是相互独立的,Kerberos认证上下文、服务端会话不会跨这两个请求复用,所以完全不会对握手请求生效。
方案1:自定义握手流程(最推荐,100%复用现有认证能力)
gorilla/websocket提供了websocket.NewClient()方法支持用户完全自定义握手请求的发送逻辑,不需要使用Dialer内置的发请求逻辑,具体实现步骤:
- 按照WebSocket协议要求构造握手GET请求,必填请求头如下:
Upgrade: websocketConnection: UpgradeSec-WebSocket-Key: 随机生成16字节内容后做base64编码即可Sec-WebSocket-Version: 13
- 用你已经封装好的、自带Kerberos自动认证的
http.Client发送上述构造完成的握手请求 - 校验服务端返回的HTTP状态码为
101 Switching Protocols,且响应头符合WebSocket握手规范后,调用websocket.NewClient(resp, nil)即可拿到可用的*websocket.Conn连接
这个方案不需要修改任何现有Kerberos认证、http.Client封装的代码,完全避免握手请求未认证的问题。
方案2:直接注入Kerberos认证头到拨号请求
如果你的Kerberos认证库支持单独生成指定服务的Authorization头值,可以直接把生成的认证头传给Dialer的拨号方法,代码示例:
// 调用你自己的Kerberos工具类生成对应WebSocket服务的认证头 authHeader := yourKerberosTool.GenerateAuthHeader(wsServiceAddr) // 构造自定义请求头 reqHeader := http.Header{} reqHeader.Set("Authorization", authHeader) // 拨号时传入自定义头,握手请求会自动携带该认证信息 conn, resp, err := websocket.DefaultDialer.Dial(wsUrl, reqHeader) if err != nil { // 错误处理逻辑 }
这个方案实现最简单,适合认证逻辑可以单独抽离的场景。
方案3:替换Dialer的传输层实现自动认证
如果你的Kerberos认证逻辑是封装在自定义http.RoundTripper中的,可以直接自定义Dialer的拨号逻辑,让握手请求走你封装好的传输层拦截逻辑,自动带上Kerberos认证头。
内容的提问来源于stack exchange,提问作者pure_Redwood
相关产品推荐
相关产品推荐

