我正在尝试通过基本身份验证建立与远程 GRPC 服务(Camunda Zeebe 网关)的连接:
client, err := zbc.NewClient(&zbc.ClientConfig{
GatewayAddress: gatewayAddress,
DialOpts: []grpcLib.DialOption{grpcLib.WithTransportCredentials(&BasicAuthCredentials{...})},
})
在实现
BasicAuthCredentials
时我有点不知所措,b/c我不知道如何在Authorization
对象中设置net.Conn
标头:
import (
"context"
"encoding/base64"
"google.golang.org/grpc/credentials"
"net"
)
type BasicAuthCredentials struct {
username string
password string
}
func (c *BasicAuthCredentials) ClientHandshake(ctx context.Context, s string, conn net.Conn) (net.Conn, credentials.AuthInfo, error) {
// Create the Basic Auth string
auth := b.username + ":" + b.password
encodedAuth := base64.StdEncoding.EncodeToString([]byte(auth))
// TODO set this encoded string as Authentication header
return conn, c, nil
}
func (c *BasicAuthCredentials) AuthType() string {
return "basic-auth"
}
// ... other methods to implement credentials.TransportCredentials
有没有办法将这些身份验证信息附加到连接中,或者我的做法从根本上是错误的?
您正在尝试直接“更改”连接,但 gRPC 已经在内部处理连接管理。您真正想要的是向每个 RPC 调用添加身份验证信息。您应该实现 GetRequestMetadata 而不是尝试 在 net.Conn 对象中设置授权标头。
实现应该是这样的 ->>
package main
import (
"context"
"encoding/base64"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
)
func basicAuth(username, password string) grpc.DialOption {
auth := username + ":" + password
encodedAuth := base64.StdEncoding.EncodeToString([]byte(auth))
return grpc.WithPerRPCCredentials(&basicAuthCreds{token: encodedAuth})
}
type basicAuthCreds struct {
token string
}
func (b *basicAuthCreds) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Basic " + b.token,
}, nil
}
func (b *basicAuthCreds) RequireTransportSecurity() bool {
return false // Set to true if using TLS
}
比这样使用它
client, err := zbc.NewClient(&zbc.ClientConfig{
GatewayAddress: gatewayAddress,
DialOpts: []grpc.DialOption{
basicAuth("username", "password"),
},
})