打开数据通道的请求不包含令牌

Posted

技术标签:

【中文标题】打开数据通道的请求不包含令牌【英文标题】:request to open data channel does not contain token 【发布时间】:2019-03-23 15:49:16 【问题描述】:

aws ssm start-session 返回 url 和令牌以打开 WebSocket 连接。 https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_StartSession.html#API_StartSession_ResponseSyntax

尝试客户端打开 WebSocket 连接: https://hashrocket.com/blog/posts/development-of-a-simple-command-line-websocket-client

但我在尝试发送类似 "type": "echo", "payload": "whoami" 的输入时遇到以下错误

websocket: close 1003 (unsupported data): Channel : 请求打开数据通道不包含令牌。

我尝试使用多个选项设置标题,例如

headers := make(http.Header)
headers.Add("Authorization", "Bearer " + token)
headers.Add("token_type", "bearer")
headers.Add("access_token", token)
headers.Add("token", token)
headers.Add("Authentication", token)

//  "github.com/gorilla/websocket"
ws, _, err := websocket.DefaultDialer.Dial(url, headers)

大部分代码与上面提到的第二个链接相同,除了尝试 wss(不是 ws)。

我想我在标题中遗漏了一些东西。任何想法?谢谢

预期行为:应该能够发送请求(如上)并成功获得响应。

【问题讨论】:

寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码. 您将不得不显示更多代码。特别是 Dial 和任何其他相关代码。 您是否能够使用稳定的预构建工具使用规定的方法连接到 websocket? 【参考方案1】:

来自DialContext 的 godoc,我知道您只是在使用拨号,但它适用。强调我的

https://godoc.org/github.com/gorilla/websocket#Dialer.DialContext

如果 WebSocket 握手失败,则同时返回 ErrBadHandshake 使用非零 *http.Response 以便调用者可以处理重定向, 身份验证等。响应正文可能不包含整个 响应并且不需要被应用程序关闭。

请尽量不要丢弃响应,以便您检查它以确定如何解决问题。

作为一般规则,如果某些事情没有解决,并且您忽略了一些返回值,请检查并查看您忽略了什么,您通常会找到解决方案。

让我知道这是否有帮助,我可以更新/删除答案。

【讨论】:

如果我理解正确,您的意思是将 Sec-Websocket-Accept 设置为令牌。 101 切换协议 101 HTTP/1.1 1 1 map[服务器:[服务器] 日期:[Thu, 18 Oct 2018 21:41:42 GMT] 连接:[升级] 升级:[websocket] Sec-Websocket-Accept:[mytokenhere]] 0xc4201dca80 0 [] false false map[] 0xc4203e2700 @Stranger 好像是要求升级连接,但我对websockets的了解基本为零。我会查看有关 gorilla websockets 的代码 101,特别是您可能想查看以下结构及其方法。 godoc.org/github.com/gorilla/websocket#Upgrader 另外,我的一个谷歌查询让我找到了最终联系 AWS 并发现这是 AWS 方面的配置问题的人,因此值得研究。 github.com/gorilla/websocket/issues/335 @RayfenWindspear 非常感谢您的时间/建议/帮助。赞赏!!!我想我会改变我的方法。幸运的是,我确实有其他方法可以解决我的问题。【参考方案2】:

您可以使用带有ssm.StartSessionOutout.StreamUrl 的默认拨号器,无需任何身份验证标头:

conn, _, err := websocket.DefaultDialer.Dial(*ssmStartSessionOutput.StreamUrl, 
 nil)
if err != nil 
    log.Fatal(err)

defer conn.Close()

然后,通过 websocket 连接发送 ssm.StartSessionOutput 令牌。这将使您摆脱相关错误:

v := struct 
    TokenValue string `json:"TokenValue"`

    TokenValue: ssmStartSessionOutput.TokenValue,
 
err := conn.WriteJSON(v)
if err != nil 
    return err

但是,SSM StartSession 的 websocket 实现几乎没有文档记录,并且充满了神秘的响应。我有更好的运气启动 session-manager-plugin 作为子进程,传递 JSON 化的 ssm.StartSessionOutput:

v := struct 
    SessionID  string `json:"SessionId"`
    StreamURL  string `json:"StreamUrl"`
    TokenValue string `json:"TokenValue"`

    SessionID:  ssmSessionOutput.SessionId,
    StreamURL:  ssmSessionOutput.StreamUrl,
    TokenValue: ssmSessionOutput.TokenValue,

j, err := json.Marshal(v)
if err != nil 
    return nil, err


cmd := exec.Command("session-manager-plugin", string(j), region, "StartSession")
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
err = cmd.Run()

【讨论】:

以上是关于打开数据通道的请求不包含令牌的主要内容,如果未能解决你的问题,请参考以下文章

Flume 代理不包含任何有效通道

怎么设置BIOS里,将光驱通道IDE打开?

[Go] golang缓冲通道实现资源池

来自 CORS 预检通道的 CORS 标头“Access-Control-Allow-Headers”中缺少令牌“x-auth”[重复]

大数据开发-Go 基础入门-包,函数,通道

(40)C#里使用WebRequest和出错:请求被中止: 未能创建 SSL/TLS 安全通道