diff --git a/changelog/unreleased/kong/basic_www_authenticate.yml b/changelog/unreleased/kong/basic_www_authenticate.yml new file mode 100644 index 000000000000..630747f005dc --- /dev/null +++ b/changelog/unreleased/kong/basic_www_authenticate.yml @@ -0,0 +1,3 @@ +message: Add missing WWW-Authenticate headers to 401 response in basic auth plugin. +type: bugfix +scope: Plugin diff --git a/kong/plugins/basic-auth/access.lua b/kong/plugins/basic-auth/access.lua index 8c76b526a536..278331ab313b 100644 --- a/kong/plugins/basic-auth/access.lua +++ b/kong/plugins/basic-auth/access.lua @@ -155,7 +155,13 @@ end local function fail_authentication() - return false, { status = 401, message = "Invalid authentication credentials" } + return false, { + status = 401, + message = "Invalid authentication credentials", + headers = { + ["WWW-Authenticate"] = realm + } + } end diff --git a/spec/03-plugins/10-basic-auth/03-access_spec.lua b/spec/03-plugins/10-basic-auth/03-access_spec.lua index acf2c4374d13..409aa36ec9cd 100644 --- a/spec/03-plugins/10-basic-auth/03-access_spec.lua +++ b/spec/03-plugins/10-basic-auth/03-access_spec.lua @@ -145,6 +145,7 @@ for _, strategy in helpers.each_strategy() do local json = cjson.decode(body) assert.not_nil(json) assert.matches("Unauthorized", json.message) + assert.equal('Basic realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("returns WWW-Authenticate header on missing credentials", function() @@ -176,6 +177,7 @@ for _, strategy in helpers.each_strategy() do local json = cjson.decode(body) assert.not_nil(json) assert.matches("Invalid authentication credentials", json.message) + assert.equal('Basic realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("returns 401 Unauthorized on invalid credentials in Proxy-Authorization", function() @@ -191,6 +193,7 @@ for _, strategy in helpers.each_strategy() do local json = cjson.decode(body) assert.not_nil(json) assert.matches("Invalid authentication credentials", json.message) + assert.equal('Basic realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("returns 401 Unauthorized on password only", function() @@ -206,6 +209,7 @@ for _, strategy in helpers.each_strategy() do local json = cjson.decode(body) assert.not_nil(json) assert.matches("Invalid authentication credentials", json.message) + assert.equal('Basic realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("returns 401 Unauthorized on username only", function() @@ -221,6 +225,7 @@ for _, strategy in helpers.each_strategy() do local json = cjson.decode(body) assert.not_nil(json) assert.matches("Invalid authentication credentials", json.message) + assert.equal('Basic realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("rejects gRPC call without credentials", function() @@ -296,6 +301,7 @@ for _, strategy in helpers.each_strategy() do local json = cjson.decode(body) assert.not_nil(json) assert.matches("Invalid authentication credentials", json.message) + assert.equal('Basic realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("authenticates valid credentials in Proxy-Authorization", function() @@ -564,6 +570,7 @@ for _, strategy in helpers.each_strategy() do } }) assert.response(res).has.status(401) + assert.equal('Key realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) it("fails 401, with no credential provided", function() @@ -575,6 +582,7 @@ for _, strategy in helpers.each_strategy() do } }) assert.response(res).has.status(401) + assert.equal('Key realm="' .. meta._NAME .. '"', res.headers["WWW-Authenticate"]) end) end)