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

连接启用IAM认证的AWS Neptune实例时触发Bad Handshake错误求助

AWS Neptune启用IAM认证后出现Websocket Bad Handshake问题解决

问题背景

  • 已启用IAM认证的AWS Neptune实例,关闭IAM认证时可正常执行CRUD操作
  • 启用IAM认证后,Lambda函数调用Neptune时出现websocket: bad handshake错误
  • Lambda函数已配置Neptune全权限,且已尝试对请求进行签名,但认证仍失败

错误日志

Failed to instantiate the new connection; setting connection state to closed.
Error creating new connection for connection pool: websocket: bad handshake
'E0104: no successful connections could be made: websocket: bad handshake'

问题代码

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
    "time"
    
    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    
    gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver"
    "github.com/aws/aws-sdk-go/aws/session"
    v4 "github.com/aws/aws-sdk-go/aws/signer/v4"
)

func main() {
    lambda.Start(lambdaHandler)
}

func lambdaHandler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
    driverConn, g = connect()
    result, err = g.AddV("User").Property("userId", "Check").Next()
    if err != nil {
        fmt.Println(err)
    }
}

func connect() {
    awsSess, err := session.NewSesionWithOptions(session.Options{
        SharedCondfigState: session.SharedConfigEnable,
    }),
    if err != nil {
        log.Fatalf("Failed to creating session: %s", err)
    }
    
    db_endpoint := os.Genenv("DB_ENDPOINT")
    connString := "wss://" +db_endpoint+":8182/gremlin"
    
    // Signing Request
    req, _ := http.NewRequest(http.MethodGet, connString, nil)
    signer := v4.NewSigner(awsSess.Config.Credentials)
    headerToUse, err := signer.Sign(req, nil, "neptune", *awsSess.Config.Region, time.Now())
    
    driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection(connString,
        func(settings *gremlingo.driverRemoteConnectionSettings) {
            settings.TraversalSource = "g"
            settings.AuthInfo.Header = headerToUse
        })
    return driverRemoteConnection, traversalSource(driverRemoteConnection)
}

func traversalSource(driverConn *gremlingo.DriverRemoteConnection) *gremlingo.GraphTraversalSource {
    return gremlingo.Traversal_().WithRemote(driverConn)
}

解决步骤

1. 修正代码拼写与语法错误

代码中存在多处拼写和语法问题,会导致签名或连接逻辑异常:

  • session.NewSesionWithOptions → 修正为 session.NewSessionWithOptions
  • SharedCondfigState → 修正为 SharedConfigState
  • os.Genenv → 修正为 os.Getenv
  • connect() 函数缺少返回类型声明,需定义为:func connect() (*gremlingo.DriverRemoteConnection, *gremlingo.GraphTraversalSource, error)(同时需处理错误返回)
  • lambdaHandler 中变量未声明,改为 driverConn, g := connect()

2. 修正AWS V4签名逻辑

Neptune的IAM签名服务名称应为neptune-db,而非neptune,且签名操作会直接修改请求Header,无需单独返回Header:

// 修正签名部分代码
req, err := http.NewRequest(http.MethodGet, connString, nil)
if err != nil {
    log.Fatalf("Failed to create request: %s", err)
}
signer := v4.NewSigner(awsSess.Config.Credentials)
// 服务名称改为neptune-db,Sign方法直接修改req.Header
_, err = signer.Sign(req, nil, "neptune-db", *awsSess.Config.Region, time.Now())
if err != nil {
    log.Fatalf("Failed to sign request: %s", err)
}

3. 调整Gremlin驱动的Header传递方式

Gremlin Go驱动的AuthInfo.Header并非用于传递AWS签名Header,需使用CustomHeaders字段传递签名后的完整Header:

driverRemoteConnection, err := gremlingo.NewDriverRemoteConnection(connString,
    func(settings *gremlingo.DriverRemoteConnectionSettings) {
        settings.TraversalSource = "g"
        // 将签名后的请求Header设置为驱动自定义Header
        settings.CustomHeaders = req.Header
    })

4. 验证IAM权限配置

确认Lambda执行角色的权限策略正确,资源ARN需匹配Neptune集群:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "neptune-db:*",
            "Resource": "arn:aws:neptune-db:你的区域:你的账号ID:cluster/你的集群ID/*"
        }
    ]
}

同时检查角色信任关系,确保允许lambda.amazonaws.com扮演该角色。

内容的提问来源于stack exchange,提问作者Vijay_Neethipudi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:05:06