Skip to content
Snippets Groups Projects
Select Git revision
  • b7dd55d7208b3c99901dc77ef15f63a8e2b5cbb2
  • master default protected
  • bugfix/fix-return-var-in-find
  • feature/upgrade2
  • v1.11.0
  • v1.10.0
  • v1.8.2
  • v1.8.1
  • v1.8.0
  • 1.7.3
  • v1.7.1
  • v1.6.1
  • v1.6.0
  • v1.5.0
  • v1.4.1
  • v1.3.0
  • v1.2.2
  • v1.2.1
  • v1.2.0
  • v1.0.1
  • v1.0.0
  • v0.0.23
  • v0.0.17
  • v0.0.10
24 results

README.md

Blame
  • grpc.go 3.39 KiB
    package auth
    
    import (
    	"context"
    
    	kitgrpc "github.com/go-kit/kit/transport/grpc"
    	"google.golang.org/grpc"
    	"google.golang.org/grpc/metadata"
    )
    
    const (
    	OAuth2IdentityMetadata = "x-perxis-identity"
    	TLSIdentityMetadata    = "x-forwarded-client-cert"
    	AccessMetadata         = "x-perxis-access"
    
    	AuthorizationMetadata = "authorization"
    )
    
    func GRPCToContext(factory *PrincipalFactory) kitgrpc.ServerRequestFunc {
    	return func(ctx context.Context, md metadata.MD) context.Context {
    		if identity := md.Get(TLSIdentityMetadata); len(identity) > 0 {
    			return WithPrincipal(ctx, factory.Principal(identity[0]))
    		}
    
    		if identity := md.Get(OAuth2IdentityMetadata); len(identity) > 0 {
    			return WithPrincipal(ctx, factory.Principal(identity[0]))
    		}
    
    		if identity := md.Get(AuthorizationMetadata); len(identity) > 0 {
    			return WithPrincipal(ctx, factory.Principal(identity[0]))
    		}
    
    		if access := md.Get(AccessMetadata); len(access) > 0 {
    			return WithPrincipal(ctx, factory.System())
    		}
    
    		return WithPrincipal(ctx, factory.Anonymous())
    	}
    }
    
    func ContextToGRPC() kitgrpc.ClientRequestFunc {
    	return func(ctx context.Context, md *metadata.MD) context.Context {
    		p := GetPrincipal(ctx)
    
    		switch p := p.(type) {
    		case *UserPrincipal:
    			if p.GetIdentity(ctx) != "" {
    				(*md)[OAuth2IdentityMetadata] = []string{p.GetIdentity(ctx)}
    			}
    		case *ClientPrincipal:
    			if ident := p.GetIdentity(ctx); ident != nil {
    				switch {
    				case ident.OAuthClientID != "":
    					(*md)[OAuth2IdentityMetadata] = []string{ident.OAuthClientID + "@clients"}
    				case ident.TLSSubject != "":
    					(*md)[TLSIdentityMetadata] = []string{ident.TLSSubject}
    				case ident.APIKey != "":
    					(*md)[AuthorizationMetadata] = []string{"API-Key " + ident.APIKey}
    
    				}
    			}
    		case *SystemPrincipal:
    			(*md)[AccessMetadata] = []string{p.GetID(ctx)}
    		}
    
    		return ctx
    	}
    }
    
    // PrincipalServerInterceptor - grpc-интерсептор, который используется для получения данных принципала из grpc-метаданы и добавления в контекст ''. В случае, если
    // сервис не использует проверку прав 'Principal' к системе, в параметрах передается пустой объект '&PrincipalFactory{}'
    func PrincipalServerInterceptor(factory *PrincipalFactory) grpc.UnaryServerInterceptor {
    	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
    		if md, ok := metadata.FromIncomingContext(ctx); ok {
    			ctx = GRPCToContext(factory)(ctx, md)
    		}
    		return handler(ctx, req)
    	}
    }
    
    // PrincipalClientInterceptor - grpc-интерсептор, который используется для получения данных принципала. В случае, если
    // сервис не использует проверку прав 'Principal' к системе, в параметрах передается пустой объект '&PrincipalFactory{}'
    func PrincipalClientInterceptor() grpc.UnaryClientInterceptor {
    	return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
    		md, ok := metadata.FromOutgoingContext(ctx)
    		if !ok {
    			md = metadata.MD{}
    		}
    		ctx = metadata.NewOutgoingContext(ContextToGRPC()(ctx, &md), md)
    		return invoker(ctx, method, req, reply, cc, opts...)
    	}
    }