3

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:关闭1003(不支持的数据):通道:打开数据通道的请求不包含令牌。

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

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)。

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

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

4

2 回答 2

1

您可以将 Default Dialer 与ssm.StartSessionOutout.StreamUrl, 一起使用,而无需任何 auth 标头:

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

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

v := struct {
    TokenValue string `json:"TokenValue"`
}{
    TokenValue: ssmStartSessionOutput.TokenValue,
 }
err := conn.WriteJSON(v)
if err != nil {
    return err
}

但是,SSM StartSession 的 websocket 实现几乎没有文档记录,并且充满了神秘的响应。我有更好的运气将会话管理器插件作为子进程启动,传递 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()
于 2018-12-18T02:12:40.413 回答
1

从 godoc for DialContext,我意识到你只是在使用拨号,但它适用。强调我的

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

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

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

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

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

于 2018-10-18T20:27:14.623 回答