diff --git a/middleware/basicauth/basicauth.go b/middleware/basicauth/basicauth.go index de29b8d9a..25d1d5046 100644 --- a/middleware/basicauth/basicauth.go +++ b/middleware/basicauth/basicauth.go @@ -19,6 +19,10 @@ type BasicAuth struct { // ServeHTTP implements the middleware.Handler interface. func (a BasicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error) { + + var hasAuth bool + var isAuthenticated bool + for _, rule := range a.Rules { for _, res := range rule.Resources { if !middleware.Path(r.URL.Path).Matches(res) { @@ -27,16 +31,26 @@ func (a BasicAuth) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error // Path matches; parse auth header username, password, ok := r.BasicAuth() + hasAuth = true // Check credentials if !ok || username != rule.Username || password != rule.Password { - w.Header().Set("WWW-Authenticate", "Basic") - return http.StatusUnauthorized, nil + continue } - + // flag set only on success authentication + isAuthenticated = true + } + } + + if hasAuth { + if !isAuthenticated { + w.Header().Set("WWW-Authenticate", "Basic") + return http.StatusUnauthorized, nil + } else { // "It's an older code, sir, but it checks out. I was about to clear them." return a.Next.ServeHTTP(w, r) } + } // Pass-thru when no paths match diff --git a/middleware/basicauth/basicauth_test.go b/middleware/basicauth/basicauth_test.go index 04d9fc83d..b590bc35b 100644 --- a/middleware/basicauth/basicauth_test.go +++ b/middleware/basicauth/basicauth_test.go @@ -84,12 +84,13 @@ func TestMultipleOverlappingRules(t *testing.T) { {"/t", http.StatusOK, "t:p1"}, {"/t/t", http.StatusOK, "t:p1"}, {"/t/t", http.StatusOK, "t1:p2"}, - + {"/a", http.StatusOK, "t1:p2"}, + {"/t/t", http.StatusUnauthorized, "t1:p3"}, + {"/t", http.StatusUnauthorized, "t1:p2"}, } for i, test := range tests { - req, err := http.NewRequest("GET", test.from, nil) if err != nil { @@ -108,7 +109,6 @@ func TestMultipleOverlappingRules(t *testing.T) { i, test.result, result) } - } }