Interraction between Middlewares errors + basicauth

I use a basicauth middleware for access to the traefik api.
If I use it alone, it works fine.
but if I use it with errors middleware that redirects 401 errors, the basicauth do not show any login prompt and just throw a 401 error from the errors middleware
the router:

"routers":{
	"api@file":{
		"entryPoints":["websecure"],
		"middlewares":["errorpage@file","ipwhitelist@file","minikea@file"],
		"service":"api@internal",
		"rule":"Host(`traefik.minikea.org`)",
		"tls":{"certResolver":"OVH"},
		"status":"enabled",
		"using":["websecure"]}}

the middlewares:

"middlewares":{
	"minikea@file":{
		"basicAuth":{"users":["minikea:$apr1$CS/5oASo$xG7nYzCWksMj.1TD0sfet1"]},
		"status":"enabled",
		"usedBy":["api@file"]},
	"errorpage@file":{
		"errors":{"status":["401-404"],"service":"fallback","query":"/{status}.jpg"},
		"status":"enabled",
		"usedBy":["api@file"]},
	"ipwhitelist@file":{
		"ipWhiteList":{"sourceRange":["127.0.0.1/32","192.168.1.0/24","172.19.0.1"]},
		"status":"enabled",
		"usedBy":["api@file"]}

logs:

traefik    | time="2020-01-22T13:08:09Z" level=debug msg="Handling connection from xx.xx.xx.xx:30532"
traefik    | time="2020-01-22T13:08:10Z" level=debug msg="Authentication failed" middlewareName=minikea@file middlewareType=BasicAuth
traefik    | time="2020-01-22T13:08:10Z" level=error msg="Caught HTTP Status Code 401, returning error page" middlewareName=errorpage@file middlewareType=customError

if I remove the errors middleware, I have this kind of logs:
incorrect login:

traefik    | time="2020-01-22T13:12:28Z" level=debug msg="Authentication failed" middlewareName=minikea@file middlewareType=BasicAuth
traefik    | time="2020-01-22T13:12:33Z" level=debug msg="Authentication failed" middlewareName=minikea@file middlewareType=BasicAuth

correct login :

traefik    | time="2020-01-22T13:12:44Z" level=debug msg="Authentication failed" middlewareName=minikea@file middlewareType=BasicAuth
traefik    | time="2020-01-22T13:12:49Z" level=debug msg="Authentication succeeded" middlewareName=minikea@file middlewareType=BasicAuth

the first 401 response should not be transfered to the second middleware or there should not be a first 401 response in the first place.

If I pass the username:password in the url, the behavior is exactly the same.

Nobody have tested that?
Is there someone who can explain what is wrong?

Where is the basicauth's expiration defined?

What do you mean by expiration?

@Minikea how long is a browser session authenticated for - and where can that be altered?

I don't know but why do you hijack my post to ask your question?

Having the same problem.
There are 2 components interacting with each other.
Requirements:

  • have basic authentication enabled
  • have custom error pages for all 400 responses (including 401).
    If we specify the middlewares in this order:
  • error pages
  • basic auth
    we get a custom 401 error page, but no login prompt from the browser. This is not the best UX.
    If we specify the middlewares in this order:
  • basic auth
  • error pages
    we get the login prompt. But if we don't have valid credentials and click cancel, we get a standard 401 error page from traefik, not our customized one.
    The problem is that the Errors middleware doesn't persist the WWW-Authenticate header, so the browser thinks it's just a regular page.

I too am facing this issue. Not sure if anyone found an answer yet. But I've had a thought.

error 401 should include in the http header how to authenticate properly.

" This status is sent with a WWW-Authenticate header that contains information on how to authorize correctly."
Citation

So I can only really see two options for it to be fixed (and I don't know how to implement either of therm)

1 The errors middleware needs to be able to pull the header from there container and merge it into the error page provided by the service the error middleware points to.

or

2 The service the error middleware points to need to retain the original responses header information. to be passed to the client.

Anyone have thoughts on how to implement these answers? Option 1 should have to be done by Traefik team or by whomever owns the errors middleware. Option 2 I have no idea how to implement as I am a novice at best html/webpage creator.

I have accounted similar problem when using traefik error middleware which will handle status code from 400-599. When I try to git clone over https or docker pull from my private docker registry, I only get 401.

My solution is add WWW-Authenticate in my error middleware service, which is a simple nginx server.

As 401 will cause traefik query /401.html, I add the following rules to my nginx server conf:

...
location = /401.html {
    add_header WWW-Authenticate 'Basic realm="Basic Auth"';
}
...

This is the most easy way to solve such problems, as I use error-page@docker as entrypoint default middleware. Though I think there must have been some error in traefik middlewares.

Hello, same problem here, 4 years and no official solution ? :slight_smile:
I tried :

  • changing my middlewares order but still the same problem
  • adding the following rules to my nginx server conf:
...
location = /401.html {
    add_header WWW-Authenticate 'Basic realm="Basic Auth"';
}
...

But it didn't fix the problem...
Same problem here and here.

It seems this is intended behavior: a middleware can act as a circuit breaker, Traefik will not process more middlewares if one fails.

If you really want the combined functionality, you probably need to create your own middlewares plugin. Source code for both should be available.