util/wrapper: allow enforcing a specific namespace when verifying requests (#1832)
* auth/jwt: add debugging * auth: more debugging * auth: more debugging * util/wrapper: don't use request context * util/wrapper: AuthHandlerNamespace * remove debugging
This commit is contained in:
parent
3f4b58b58c
commit
a5e9dc21ca
@ -44,11 +44,16 @@ func newService(opts ...Option) Service {
|
|||||||
options.Client = wrapper.CacheClient(cacheFn, options.Client)
|
options.Client = wrapper.CacheClient(cacheFn, options.Client)
|
||||||
options.Client = wrapper.AuthClient(authFn, options.Client)
|
options.Client = wrapper.AuthClient(authFn, options.Client)
|
||||||
|
|
||||||
|
// pass the services auth namespace to the auth handler so it
|
||||||
|
// uses this to verify requests, preventing the reliance on the
|
||||||
|
// unsecure Micro-Namespace header.
|
||||||
|
handlerNS := wrapper.AuthHandlerNamespace(options.Auth.Options().Issuer)
|
||||||
|
|
||||||
// wrap the server to provide handler stats
|
// wrap the server to provide handler stats
|
||||||
options.Server.Init(
|
options.Server.Init(
|
||||||
server.WrapHandler(wrapper.HandlerStats(stats.DefaultStats)),
|
server.WrapHandler(wrapper.HandlerStats(stats.DefaultStats)),
|
||||||
server.WrapHandler(wrapper.TraceHandler(trace.DefaultTracer)),
|
server.WrapHandler(wrapper.TraceHandler(trace.DefaultTracer)),
|
||||||
server.WrapHandler(wrapper.AuthHandler(authFn)),
|
server.WrapHandler(wrapper.AuthHandler(authFn, handlerNS)),
|
||||||
)
|
)
|
||||||
|
|
||||||
// set opts
|
// set opts
|
||||||
|
@ -187,10 +187,28 @@ func AuthClient(auth func() auth.Auth, c client.Client) client.Client {
|
|||||||
return &authWrapper{c, auth}
|
return &authWrapper{c, auth}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AuthHandlerNamespace(ns string) AuthHandlerOption {
|
||||||
|
return func(o *AuthHandlerOptions) {
|
||||||
|
o.Namespace = ns
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type AuthHandlerOption func(o *AuthHandlerOptions)
|
||||||
|
|
||||||
|
type AuthHandlerOptions struct {
|
||||||
|
Namespace string
|
||||||
|
}
|
||||||
|
|
||||||
// AuthHandler wraps a server handler to perform auth
|
// AuthHandler wraps a server handler to perform auth
|
||||||
func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
|
func AuthHandler(fn func() auth.Auth, opts ...AuthHandlerOption) server.HandlerWrapper {
|
||||||
return func(h server.HandlerFunc) server.HandlerFunc {
|
return func(h server.HandlerFunc) server.HandlerFunc {
|
||||||
return func(ctx context.Context, req server.Request, rsp interface{}) error {
|
return func(ctx context.Context, req server.Request, rsp interface{}) error {
|
||||||
|
// parse the options
|
||||||
|
options := AuthHandlerOptions{}
|
||||||
|
for _, o := range opts {
|
||||||
|
o(&options)
|
||||||
|
}
|
||||||
|
|
||||||
// get the auth.Auth interface
|
// get the auth.Auth interface
|
||||||
a := fn()
|
a := fn()
|
||||||
|
|
||||||
@ -235,12 +253,22 @@ func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
|
|||||||
Endpoint: req.Endpoint(),
|
Endpoint: req.Endpoint(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify the caller has access to the resource
|
// Normal services set the namespace to prevent it being overriden
|
||||||
err := a.Verify(account, res, auth.VerifyContext(ctx))
|
// by setting the Namespace header, however this isn't the case for
|
||||||
if err != nil && account != nil {
|
// the proxy which uses the namespace header when routing requests
|
||||||
|
// to a specific network.
|
||||||
|
if len(options.Namespace) == 0 {
|
||||||
|
options.Namespace = ns
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the caller has access to the resource.
|
||||||
|
err := a.Verify(account, res, auth.VerifyNamespace(options.Namespace))
|
||||||
|
if err == auth.ErrForbidden && account != nil {
|
||||||
return errors.Forbidden(req.Service(), "Forbidden call made to %v:%v by %v", req.Service(), req.Endpoint(), account.ID)
|
return errors.Forbidden(req.Service(), "Forbidden call made to %v:%v by %v", req.Service(), req.Endpoint(), account.ID)
|
||||||
} else if err != nil {
|
} else if err == auth.ErrForbidden {
|
||||||
return errors.Unauthorized(req.Service(), "Unauthorized call made to %v:%v", req.Service(), req.Endpoint())
|
return errors.Unauthorized(req.Service(), "Unauthorized call made to %v:%v", req.Service(), req.Endpoint())
|
||||||
|
} else if err != nil {
|
||||||
|
return errors.InternalServerError(req.Service(), "Error authorizing request: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is an account, set it in the context
|
// There is an account, set it in the context
|
||||||
|
Loading…
x
Reference in New Issue
Block a user