From bfa76b1edeae9b6af59e5fa2e342abcbe7f5f532 Mon Sep 17 00:00:00 2001 From: Julien Andrieux Date: Fri, 6 Oct 2017 15:39:27 +0200 Subject: [PATCH] Add interceptor on the server to authenticate client --- server/main.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/server/main.go b/server/main.go index 7b3a3e1..817f4db 100644 --- a/server/main.go +++ b/server/main.go @@ -4,12 +4,59 @@ import ( "fmt" "log" "net" + "strings" + + "golang.org/x/net/context" "gitlab.com/pantomath-io/demo-grpc/api" "google.golang.org/grpc" "google.golang.org/grpc/credentials" + "google.golang.org/grpc/metadata" ) +// private type for Context keys +type contextKey int + +const ( + clientIDKey contextKey = iota +) + +// authenticateAgent check the client credentials +func authenticateClient(ctx context.Context, s *api.Server) (string, error) { + if md, ok := metadata.FromIncomingContext(ctx); ok { + clientLogin := strings.Join(md["login"], "") + clientPassword := strings.Join(md["password"], "") + + if clientLogin != "john" { + return "", fmt.Errorf("unknown user %s", clientLogin) + } + if clientPassword != "doe" { + return "", fmt.Errorf("bad password %s", clientPassword) + } + + log.Printf("authenticated client: %s", clientLogin) + + return "42", nil + } + return "", fmt.Errorf("missing credentials") +} + +// unaryInterceptor call authenticateClient with current context +func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + s, ok := info.Server.(*api.Server) + if !ok { + return nil, fmt.Errorf("unable to cast server") + } + clientID, err := authenticateClient(ctx, s) + if err != nil { + return nil, err + } + + ctx = context.WithValue(ctx, clientIDKey, clientID) + + return handler(ctx, req) +} + // main start a gRPC server and waits for connection func main() { // create a listener on TCP port 7777 @@ -28,7 +75,8 @@ func main() { } // Create an array of gRPC options with the credentials - opts := []grpc.ServerOption{grpc.Creds(creds)} + opts := []grpc.ServerOption{grpc.Creds(creds), + grpc.UnaryInterceptor(unaryInterceptor)} // create a gRPC server object grpcServer := grpc.NewServer(opts...) -- 2.44.0