ory / oathkeeper

A cloud native Identity & Access Proxy / API (IAP) and Access Control Decision API that authenticates, authorizes, and mutates incoming HTTP(s) requests. Inspired by the BeyondCorp / Zero Trust white paper. Written in Go.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=hydra
Apache License 2.0
3.24k stars 357 forks source link

Basic Authorization header result in Unauthorized when using `anonymous` authenticator handler #1137

Open sayoun opened 1 year ago

sayoun commented 1 year ago

Preflight checklist

Ory Network Project

No response

Describe the bug

When a rule is defined with only one anonymous authenticator, an allow authorizer and a noop mutator, the incoming HTTP request will still fail and result in a 401 Unauthorized when the incoming HTTP call has a basic authorization header.

Reproducing the bug

  1. using the ory examples
    git clone git@github.com:ory/examples
    cd examples/oathkeeper/01-basic
    docker-compose up --build
  2. make a curl call to the endpoint without any header, it works
    curl -s http://127.0.0.1:8080/hello 
    Hello 👋
  3. make a curl call to the endpoint with a basic authorization header, it will fail
    curl -s -H "Authorization: Basic b3J5Om9yeQ==" http://127.0.0.1:8080/hello 
    {"error":{"code":401,"status":"Unauthorized","message":"Access credentials are invalid"}}

Relevant log output

oathkeeper_1  | [cors] 2023/09/14 15:10:55 Handler: Actual request
oathkeeper_1  | [cors] 2023/09/14 15:10:55   Actual request no headers added: missing origin
oathkeeper_1  | {"http_request":{"headers":{"accept":"*/*","authorization":"Value is sensitive and has been redacted. To see the value set config key \"log.leak_sensitive_values = true\" or environment variable \"LOG_LEAK_SENSITIVE_VALUES=true\".","user-agent":"curl/7.68.0"},"host":"127.0.0.1:8080","method":"GET","path":"/hello","query":null,"remote":"173.2.1.1:33144","scheme":"http"},"level":"info","msg":"started handling request","time":"2023-09-14T15:10:55.179673755Z"}
oathkeeper_1  | {"audience":"application","error":{"debug":"","message":"Access credentials are invalid","reason":"","stack_trace":"\ngithub.com/ory/oathkeeper/proxy.(*requestHandler).HandleRequest\n\t/project/proxy/request_handler.go:236\ngithub.com/ory/oathkeeper/proxy.(*Proxy).Rewrite\n\t/project/proxy/proxy.go:133\nnet/http/httputil.(*ReverseProxy).ServeHTTP\n\t/usr/local/go/src/net/http/httputil/reverseproxy.go:433\ngithub.com/urfave/negroni.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2122\ngithub.com/rs/cors.(*Cors).Handler.func1\n\t/go/pkg/mod/github.com/rs/cors@v1.8.2/cors.go:231\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2122\ngithub.com/ory/x/corsx.ContextualizedMiddleware.func1\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/corsx/middleware.go:30\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/reqlog.(*Middleware).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/reqlog/middleware.go:142\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/metrics.(*Middleware).ServeHTTP\n\t/project/metrics/middleware.go:103\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/metricsx/middleware.go:272\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/urfave/negroni.(*Negroni).ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:96\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*Handler).ServeHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.36.4/handler.go:204\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2936\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1995\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1598","status":"Unauthorized","status_code":401},"granted":false,"http_host":"127.0.0.1:8080","http_method":"GET","http_url":"http://127.0.0.1:8080/hello","http_user_agent":"curl/7.68.0","level":"warning","msg":"No authentication handler was responsible for handling the authentication request","reason_id":"authentication_handler_no_match","rule_id":"api:protected","service_name":"ORY Oathkeeper","service_version":"v0.40.6","time":"2023-09-14T15:10:55.180139123Z"}
oathkeeper_1  | {"audience":"application","error":{"debug":"","message":"Access credentials are invalid","reason":"","stack_trace":"\ngithub.com/ory/oathkeeper/proxy.(*requestHandler).HandleRequest\n\t/project/proxy/request_handler.go:236\ngithub.com/ory/oathkeeper/proxy.(*Proxy).Rewrite\n\t/project/proxy/proxy.go:133\nnet/http/httputil.(*ReverseProxy).ServeHTTP\n\t/usr/local/go/src/net/http/httputil/reverseproxy.go:433\ngithub.com/urfave/negroni.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2122\ngithub.com/rs/cors.(*Cors).Handler.func1\n\t/go/pkg/mod/github.com/rs/cors@v1.8.2/cors.go:231\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2122\ngithub.com/ory/x/corsx.ContextualizedMiddleware.func1\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/corsx/middleware.go:30\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/reqlog.(*Middleware).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/reqlog/middleware.go:142\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/metrics.(*Middleware).ServeHTTP\n\t/project/metrics/middleware.go:103\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/metricsx/middleware.go:272\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/urfave/negroni.(*Negroni).ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:96\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*Handler).ServeHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.36.4/handler.go:204\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2936\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1995\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1598","status":"Unauthorized","status_code":401},"granted":false,"http_host":"127.0.0.1:8080","http_method":"GET","http_url":"http://127.0.0.1:8080/hello","http_user_agent":"curl/7.68.0","level":"warning","msg":"Access request denied","service_name":"ORY Oathkeeper","service_version":"v0.40.6","time":"2023-09-14T15:10:55.18027065Z"}
oathkeeper_1  | {"audience":"application","error":{"debug":"","message":"Access credentials are invalid","reason":"","stack_trace":"\ngithub.com/ory/oathkeeper/proxy.(*requestHandler).HandleRequest\n\t/project/proxy/request_handler.go:236\ngithub.com/ory/oathkeeper/proxy.(*Proxy).Rewrite\n\t/project/proxy/proxy.go:133\nnet/http/httputil.(*ReverseProxy).ServeHTTP\n\t/usr/local/go/src/net/http/httputil/reverseproxy.go:433\ngithub.com/urfave/negroni.Wrap.func1\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:46\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2122\ngithub.com/rs/cors.(*Cors).Handler.func1\n\t/go/pkg/mod/github.com/rs/cors@v1.8.2/cors.go:231\nnet/http.HandlerFunc.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2122\ngithub.com/ory/x/corsx.ContextualizedMiddleware.func1\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/corsx/middleware.go:30\ngithub.com/urfave/negroni.HandlerFunc.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:29\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/reqlog.(*Middleware).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/reqlog/middleware.go:142\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/oathkeeper/metrics.(*Middleware).ServeHTTP\n\t/project/metrics/middleware.go:103\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/ory/x/metricsx.(*Service).ServeHTTP\n\t/go/pkg/mod/github.com/ory/x@v0.0.565/metricsx/middleware.go:272\ngithub.com/urfave/negroni.middleware.ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:38\ngithub.com/urfave/negroni.(*Negroni).ServeHTTP\n\t/go/pkg/mod/github.com/urfave/negroni@v1.0.0/negroni.go:96\ngo.opentelemetry.io/contrib/instrumentation/net/http/otelhttp.(*Handler).ServeHTTP\n\t/go/pkg/mod/go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp@v0.36.4/handler.go:204\nnet/http.serverHandler.ServeHTTP\n\t/usr/local/go/src/net/http/server.go:2936\nnet/http.(*conn).serve\n\t/usr/local/go/src/net/http/server.go:1995\nruntime.goexit\n\t/usr/local/go/src/runtime/asm_amd64.s:1598","status":"Unauthorized","status_code":401},"http_request":{"headers":{"accept":"*/*","authorization":"Value is sensitive and has been redacted. To see the value set config key \"log.leak_sensitive_values = true\" or environment variable \"LOG_LEAK_SENSITIVE_VALUES=true\".","user-agent":"curl/7.68.0"},"host":"127.0.0.1:8080","method":"GET","path":"/hello","query":null,"remote":"173.2.1.1:33144","scheme":"http"},"http_response":{"status_code":401},"level":"info","msg":"An error occurred while handling a request","service_name":"ORY Oathkeeper","service_version":"v0.40.6","time":"2023-09-14T15:10:55.180503171Z"}
oathkeeper_1  | {"http_request":{"headers":{"accept":"*/*","authorization":"Value is sensitive and has been redacted. To see the value set config key \"log.leak_sensitive_values = true\" or environment variable \"LOG_LEAK_SENSITIVE_VALUES=true\".","user-agent":"curl/7.68.0"},"host":"127.0.0.1:8080","method":"GET","path":"/hello","query":null,"remote":"173.2.1.1:33144","scheme":"http"},"http_response":{"headers":{"content-type":"application/json","vary":"Origin"},"size":90,"status":401,"text_status":"Unauthorized","took":985002},"level":"info","msg":"completed handling request","time":"2023-09-14T15:10:55.180618776Z"}

Relevant configuration

No response

Version

v0.40.0

On which operating system are you observing this issue?

Linux

In which environment are you deploying?

Docker

Additional Context

This issue is related to this code https://github.com/ory/oathkeeper/blob/master/proxy/request_handler.go#L208-L210 where the ErrAuthenticatorNotResponsible is correctly raised but the found variable is not set to true when there is only one authenticator which is of type anonymous