From 3f67edcdc16bd40babf31ad07e89540f144ea36c Mon Sep 17 00:00:00 2001 From: ybv Date: Sat, 3 Oct 2015 23:35:20 -0700 Subject: [PATCH] Add WWW-Authenticate header for reponses w/ status 401 Unauthorized. --- kong/plugins/basic-auth/access.lua | 1 + kong/plugins/key-auth/access.lua | 1 + spec/plugins/basic-auth/access_spec.lua | 11 +++++---- spec/plugins/key-auth/access_spec.lua | 31 +++++++++++++++---------- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/kong/plugins/basic-auth/access.lua b/kong/plugins/basic-auth/access.lua index b025e1c8acfa..39db179efaa4 100644 --- a/kong/plugins/basic-auth/access.lua +++ b/kong/plugins/basic-auth/access.lua @@ -85,6 +85,7 @@ function _M.execute(conf) -- If both headers are missing, return 401 if not (ngx.req.get_headers()[AUTHORIZATION] or ngx.req.get_headers()[PROXY_AUTHORIZATION]) then ngx.ctx.stop_phases = true + ngx.header["WWW-Authenticate"] = "Basic realm=\""..constants.NAME.."\"" return responses.send_HTTP_UNAUTHORIZED() end diff --git a/kong/plugins/key-auth/access.lua b/kong/plugins/key-auth/access.lua index 7e04e9fac09f..3ff45b8c8c3a 100644 --- a/kong/plugins/key-auth/access.lua +++ b/kong/plugins/key-auth/access.lua @@ -72,6 +72,7 @@ function _M.execute(conf) -- No key found in the request's headers or parameters if not key_found then ngx.ctx.stop_phases = true + ngx.header["WWW-Authenticate"] = "Key realm=\""..constants.NAME.."\"" return responses.send_HTTP_UNAUTHORIZED("No API Key found in headers, body or querystring") end diff --git a/spec/plugins/basic-auth/access_spec.lua b/spec/plugins/basic-auth/access_spec.lua index 8edc008f964e..8c87ce7c0841 100644 --- a/spec/plugins/basic-auth/access_spec.lua +++ b/spec/plugins/basic-auth/access_spec.lua @@ -1,5 +1,6 @@ local spec_helper = require "spec.spec_helpers" local http_client = require "kong.tools.http_client" +local constants = require "kong.constants" local cjson = require "cjson" local PROXY_URL = spec_helper.PROXY_URL @@ -32,10 +33,11 @@ describe("Authentication Plugin", function() describe("Basic Authentication", function() - it("should return invalid credentials when the credential is missing", function() - local response, status = http_client.get(PROXY_URL.."/get", {}, {host = "basicauth.com"}) + it("should return invalid credentials and www-authenticate header when the credential is missing", function() + local response, status, headers = http_client.get(PROXY_URL.."/get", {}, {host = "basicauth.com"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Basic realm=\""..constants.NAME.."\"") assert.equal("Unauthorized", body.message) end) @@ -67,10 +69,11 @@ describe("Authentication Plugin", function() assert.equal("Invalid authentication credentials", body.message) end) - it("should reply 401 when authorization is missing", function() - local response, status = http_client.get(PROXY_URL.."/get", {}, {host = "basicauth.com", authorization123 = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="}) + it("should reply 401 and www-authenticate header when authorization is missing", function() + local response, status, headers = http_client.get(PROXY_URL.."/get", {}, {host = "basicauth.com", authorization123 = "Basic dXNlcm5hbWU6cGFzc3dvcmQ="}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Basic realm=\""..constants.NAME.."\"") assert.equal("Unauthorized", body.message) end) diff --git a/spec/plugins/key-auth/access_spec.lua b/spec/plugins/key-auth/access_spec.lua index b5f9d38d7765..0112e0e03ff0 100644 --- a/spec/plugins/key-auth/access_spec.lua +++ b/spec/plugins/key-auth/access_spec.lua @@ -1,5 +1,6 @@ local spec_helper = require "spec.spec_helpers" local http_client = require "kong.tools.http_client" +local constants = require "kong.constants" local cjson = require "cjson" local STUB_GET_URL = spec_helper.STUB_GET_URL @@ -35,10 +36,11 @@ describe("Authentication Plugin", function() describe("Query Authentication", function() - it("should return invalid credentials when the credential is missing", function() - local response, status = http_client.get(STUB_GET_URL, {}, {host = "keyauth1.com"}) + it("should return invalid credentials and www-authenticate header when the credential is missing", function() + local response, status, headers = http_client.get(STUB_GET_URL, {}, {host = "keyauth1.com"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Key realm=\""..constants.NAME.."\"") assert.equal("No API Key found in headers, body or querystring", body.message) end) @@ -49,24 +51,27 @@ describe("Authentication Plugin", function() assert.equal("Invalid authentication credentials", body.message) end) - it("should reply 401 when the credential parameter is missing", function() - local response, status = http_client.get(STUB_GET_URL, {apikey123 = "apikey123"}, {host = "keyauth1.com"}) + it("should reply with 401 and www-authenticate header when the credential parameter is missing", function() + local response, status, headers = http_client.get(STUB_GET_URL, {apikey123 = "apikey123"}, {host = "keyauth1.com"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Key realm=\""..constants.NAME.."\"") assert.equal("No API Key found in headers, body or querystring", body.message) end) - it("should reply 401 when the credential parameter name is wrong in GET", function() - local response, status = http_client.get(STUB_GET_URL, {apikey123 = "apikey123"}, {host = "keyauth1.com"}) + it("should reply 401 and www-authenticate header when the credential parameter name is wrong in GET", function() + local response, status, headers = http_client.get(STUB_GET_URL, {apikey123 = "apikey123"}, {host = "keyauth1.com"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Key realm=\""..constants.NAME.."\"") assert.equal("No API Key found in headers, body or querystring", body.message) end) - it("should reply 401 when the credential parameter name is wrong in POST", function() - local response, status = http_client.post(STUB_POST_URL, {apikey123 = "apikey123"}, {host = "keyauth1.com"}) + it("should reply 401 and www-authenticate header when the credential parameter name is wrong in POST", function() + local response, status, headers = http_client.post(STUB_POST_URL, {apikey123 = "apikey123"}, {host = "keyauth1.com"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Key realm=\""..constants.NAME.."\"") assert.equal("No API Key found in headers, body or querystring", body.message) end) @@ -77,17 +82,19 @@ describe("Authentication Plugin", function() assert.equal("apikey123", parsed_response.queryString.apikey) end) - it("should reply 401 when the credential parameter name is wrong in GET header", function() - local response, status = http_client.get(STUB_GET_URL, {}, {host = "keyauth1.com", apikey123 = "apikey123"}) + it("should reply 401 and www-authenticate header when the credential parameter name is wrong in GET header", function() + local response, status, headers = http_client.get(STUB_GET_URL, {}, {host = "keyauth1.com", apikey123 = "apikey123"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Key realm=\""..constants.NAME.."\"") assert.equal("No API Key found in headers, body or querystring", body.message) end) - it("should reply 401 when the credential parameter name is wrong in POST header", function() - local response, status = http_client.post(STUB_POST_URL, {}, {host = "keyauth1.com", apikey123 = "apikey123"}) + it("should reply 401 and www-authenticate header when the credential parameter name is wrong in POST header", function() + local response, status, headers = http_client.post(STUB_POST_URL, {}, {host = "keyauth1.com", apikey123 = "apikey123"}) local body = cjson.decode(response) assert.equal(401, status) + assert.equal(headers["www-authenticate"], "Key realm=\""..constants.NAME.."\"") assert.equal("No API Key found in headers, body or querystring", body.message) end)