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:
ben-toogood 2020-07-14 10:27:15 +01:00 committed by GitHub
parent 3f4b58b58c
commit a5e9dc21ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 6 deletions

View File

@ -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

View File

@ -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