Go GRPC中的授权注释



我有一台GRPC服务器,其API经过授权,如:

func (s *MyServer) MyAPI(ctx context.Context, req MyAPIRequest) (MyAPIResponse, error) {
isAuthorized, err = s.IsAuthorized(ctx, req.UserId, Role.User) // other APIs may use a different authorization function than IsAuthorized
if err != nil {
return nil, err
}

if !isAuthorized {
return nil,  status.Error(codes.PermissionDenied, "not authorized")
}
// rest of API code
}

我想知道如何:

  1. 简化授权逻辑的使用,就像注释一样。我更熟悉Java,它就像函数上方的@Authorize(ctx = ctx, req = req, role = Role.User)
  2. 要求对API进行授权检查,以便在至少一个API缺少授权的情况下生成失败。我在用巴泽尔。请注意,并非所有func (s *MyServer)都是API

这是我的想法:

    • 创建一个YAML文件,其中包含方法名称到授权规则的键值对。示例是MyAPI: IsUserIdAuthorizedAsUser,其将被转换为s.IsAuthorized(ctx, req.UserId, Role.User)
    • 创建一个拦截器,用于查找请求的方法名的authz规则并调用相应的authz函数
  1. 有一个bazel构建规则,该规则解析rpc的原型文件,这些文件都是API方法名称,如果不是所有的方法名称都在规则列表中,则会失败。我还不知道该怎么做

如果您对我的想法有任何建议或更好的方法,我们将不胜感激。

我将使用拦截器(grpc.UnaryInterceptor(来处理身份验证/授权过程。它类似于经典的spring过滤器(java世界(。

您可以在此处阅读有关拦截器的信息:https://shijuvar.medium.com/writing-grpc-interceptors-in-go-bf3e7671fe48

你可以很容易地链接多个拦截器,或者每个grpc方法都有拦截器。

下面是我几个月前写的一个拦截器(它使用JWT作为身份验证机制(。您可以将其用作示例:

func (jwt JwtInterceptor) Interceptor(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler) (interface{}, error) {
md, _ := metadata.FromIncomingContext(ctx)
token := md["jwt"]
if token == nil {
return nil, errors.New("token not present")
}
apiClaims, err := jwt.decoder.Parse(token[0])
if err != nil {
return nil, errors.New("token signature not valid")
}
return handler(context.WithValue(ctx, "jwt", apiClaims), req)
}

最新更新