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.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
|
||||
options.Server.Init(
|
||||
server.WrapHandler(wrapper.HandlerStats(stats.DefaultStats)),
|
||||
server.WrapHandler(wrapper.TraceHandler(trace.DefaultTracer)),
|
||||
server.WrapHandler(wrapper.AuthHandler(authFn)),
|
||||
server.WrapHandler(wrapper.AuthHandler(authFn, handlerNS)),
|
||||
)
|
||||
|
||||
// set opts
|
||||
|
@ -187,10 +187,28 @@ func AuthClient(auth func() auth.Auth, c client.Client) client.Client {
|
||||
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
|
||||
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(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
|
||||
a := fn()
|
||||
|
||||
@ -235,12 +253,22 @@ func AuthHandler(fn func() auth.Auth) server.HandlerWrapper {
|
||||
Endpoint: req.Endpoint(),
|
||||
}
|
||||
|
||||
// Verify the caller has access to the resource
|
||||
err := a.Verify(account, res, auth.VerifyContext(ctx))
|
||||
if err != nil && account != nil {
|
||||
// Normal services set the namespace to prevent it being overriden
|
||||
// by setting the Namespace header, however this isn't the case for
|
||||
// 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)
|
||||
} else if err != nil {
|
||||
} else if err == auth.ErrForbidden {
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user