github.com/infraboard/keyauth@v0.8.1/client/interceptor/grpc.go (about) 1 package interceptor 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/infraboard/mcube/logger" 8 "github.com/infraboard/mcube/logger/zap" 9 "google.golang.org/grpc" 10 "google.golang.org/grpc/codes" 11 "google.golang.org/grpc/metadata" 12 "google.golang.org/grpc/status" 13 14 "github.com/infraboard/keyauth/apps/micro" 15 "github.com/infraboard/keyauth/client" 16 "github.com/infraboard/keyauth/common/header" 17 ) 18 19 // GrpcAuthUnaryServerInterceptor returns a new unary server interceptor for auth. 20 func GrpcAuthUnaryServerInterceptor(c *client.Client) grpc.UnaryServerInterceptor { 21 return newGrpcAuther(c).Auth 22 } 23 24 func newGrpcAuther(c *client.Client) *grpcAuther { 25 return &grpcAuther{ 26 log: zap.L().Named("Grpc Auther"), 27 keyauth: c, 28 } 29 } 30 31 // internal todo 32 type grpcAuther struct { 33 log logger.Logger 34 keyauth *client.Client 35 } 36 37 func (a *grpcAuther) Auth( 38 ctx context.Context, req interface{}, 39 info *grpc.UnaryServerInfo, 40 handler grpc.UnaryHandler, 41 ) (resp interface{}, err error) { 42 // 重上下文中获取认证信息 43 md, ok := metadata.FromIncomingContext(ctx) 44 if !ok { 45 return nil, fmt.Errorf("ctx is not an grpc incoming context") 46 } 47 48 clientId, clientSecret := a.GetClientCredentialsFromMeta(md) 49 50 // 校验调用的客户端凭证是否有效 51 if err := a.validateServiceCredential(clientId, clientSecret); err != nil { 52 return nil, err 53 } 54 55 resp, err = handler(ctx, req) 56 return resp, err 57 } 58 59 func (a *grpcAuther) GetClientCredentialsFromMeta(md metadata.MD) ( 60 clientId, clientSecret string) { 61 cids := md.Get(header.ClientHeaderKey) 62 sids := md.Get(header.ClientSecretKey) 63 if len(cids) > 0 { 64 clientId = cids[0] 65 } 66 if len(sids) > 0 { 67 clientSecret = sids[0] 68 } 69 return 70 } 71 72 func (a *grpcAuther) validateServiceCredential(clientId, clientSecret string) error { 73 if clientId == "" && clientSecret == "" { 74 return status.Errorf(codes.Unauthenticated, "client_id or client_secret is \"\"") 75 } 76 77 vsReq := micro.NewValidateClientCredentialRequest(clientId, clientSecret) 78 _, err := a.keyauth.Micro().ValidateClientCredential(context.Background(), vsReq) 79 if err != nil { 80 return status.Errorf(codes.Unauthenticated, "service auth error, %s", err) 81 } 82 83 return nil 84 }