Auth Wrapper (#1174)

* Auth Wrapper

* Tweak cmd flag

* auth_excludes => auth_exclude

* Make Auth.Excludes variadic

* Use metadata.Get (passes through http and http2 it will go through various case formats)

* fix auth wrapper auth.Auth interface initialisation

Co-authored-by: Asim Aslam <asim@aslam.me>
This commit is contained in:
ben-toogood
2020-02-10 08:26:28 +00:00
committed by GitHub
parent c706afcf04
commit 4401c12e6c
9 changed files with 111 additions and 18 deletions

View File

@@ -4,9 +4,11 @@ import (
"context"
"strings"
"github.com/micro/go-micro/v2/auth"
"github.com/micro/go-micro/v2/client"
"github.com/micro/go-micro/v2/debug/stats"
"github.com/micro/go-micro/v2/debug/trace"
"github.com/micro/go-micro/v2/errors"
"github.com/micro/go-micro/v2/metadata"
"github.com/micro/go-micro/v2/server"
)
@@ -25,6 +27,7 @@ type traceWrapper struct {
var (
HeaderPrefix = "Micro-"
BearerSchema = "Bearer "
)
func (c *clientWrapper) setHeaders(ctx context.Context) context.Context {
@@ -132,3 +135,47 @@ func TraceHandler(t trace.Tracer) server.HandlerWrapper {
}
}
}
// AuthHandler wraps a server handler to perform auth
func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
return func(h server.HandlerFunc) server.HandlerFunc {
return func(ctx context.Context, req server.Request, rsp interface{}) error {
// get the auth.Auth interface
a := fn()
// Extract endpoint and remove service name prefix
// (e.g. Platform.ListServices => ListServices)
var endpoint string
if ec := strings.Split(req.Endpoint(), "."); len(ec) == 2 {
endpoint = ec[1]
}
// Check for endpoints excluded from auth. If the endpoint
// matches, execute the handler and return
for _, e := range a.Options().Excludes {
if e == endpoint {
return h(ctx, req, rsp)
}
}
// Extract the token if present. Note: if noop is being used
// then the token can be blank without erroring
var token string
if header, ok := metadata.Get(ctx, "Authorization"); ok {
// Ensure the correct scheme is being used
if !strings.HasPrefix(header, BearerSchema) {
return errors.Unauthorized("go.micro.auth", "invalid authorization header. expected Bearer schema")
}
token = header[len(BearerSchema):]
}
// Validate the token
if _, err := a.Validate(token); err != nil {
return err
}
return h(ctx, req, rsp)
}
}
}