mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* Adding a way to inject a request ID It is very useful to associate a request ID to each incoming request, this change allows to provide a function to do that via Server Option. The change comes with a default function which will generate a new request ID. The request ID is put in the request context along with a common logger which always logs the request-id We add gRPC interceptors to the server so it can get the request ID out of the gRPC metadata and put it in the common logger stored in the context so as all the log lines using the common logger from the context will have the request ID logged
68 lines
2.7 KiB
Go
68 lines
2.7 KiB
Go
// Copyright 2016 Michal Witkowski. All Rights Reserved.
|
|
// See LICENSE for licensing terms.
|
|
|
|
package grpc_auth
|
|
|
|
import (
|
|
"github.com/grpc-ecosystem/go-grpc-middleware"
|
|
"golang.org/x/net/context"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// AuthFunc is the pluggable function that performs authentication.
|
|
//
|
|
// The passed in `Context` will contain the gRPC metadata.MD object (for header-based authentication) and
|
|
// the peer.Peer information that can contain transport-based credentials (e.g. `credentials.AuthInfo`).
|
|
//
|
|
// The returned context will be propagated to handlers, allowing user changes to `Context`. However,
|
|
// please make sure that the `Context` returned is a child `Context` of the one passed in.
|
|
//
|
|
// If error is returned, its `grpc.Code()` will be returned to the user as well as the verbatim message.
|
|
// Please make sure you use `codes.Unauthenticated` (lacking auth) and `codes.PermissionDenied`
|
|
// (authed, but lacking perms) appropriately.
|
|
type AuthFunc func(ctx context.Context) (context.Context, error)
|
|
|
|
// ServiceAuthFuncOverride allows a given gRPC service implementation to override the global `AuthFunc`.
|
|
//
|
|
// If a service implements the AuthFuncOverride method, it takes precedence over the `AuthFunc` method,
|
|
// and will be called instead of AuthFunc for all method invocations within that service.
|
|
type ServiceAuthFuncOverride interface {
|
|
AuthFuncOverride(ctx context.Context, fullMethodName string) (context.Context, error)
|
|
}
|
|
|
|
// UnaryServerInterceptor returns a new unary server interceptors that performs per-request auth.
|
|
func UnaryServerInterceptor(authFunc AuthFunc) grpc.UnaryServerInterceptor {
|
|
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
|
var newCtx context.Context
|
|
var err error
|
|
if overrideSrv, ok := info.Server.(ServiceAuthFuncOverride); ok {
|
|
newCtx, err = overrideSrv.AuthFuncOverride(ctx, info.FullMethod)
|
|
} else {
|
|
newCtx, err = authFunc(ctx)
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler(newCtx, req)
|
|
}
|
|
}
|
|
|
|
// StreamServerInterceptor returns a new unary server interceptors that performs per-request auth.
|
|
func StreamServerInterceptor(authFunc AuthFunc) grpc.StreamServerInterceptor {
|
|
return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
|
|
var newCtx context.Context
|
|
var err error
|
|
if overrideSrv, ok := srv.(ServiceAuthFuncOverride); ok {
|
|
newCtx, err = overrideSrv.AuthFuncOverride(stream.Context(), info.FullMethod)
|
|
} else {
|
|
newCtx, err = authFunc(stream.Context())
|
|
}
|
|
if err != nil {
|
|
return err
|
|
}
|
|
wrapped := grpc_middleware.WrapServerStream(stream)
|
|
wrapped.WrappedContext = newCtx
|
|
return handler(srv, wrapped)
|
|
}
|
|
}
|