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:
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user