Skip to content

Commit

Permalink
Change oauth2 authentication challenge to follow rfc2616, rfc2617, an…
Browse files Browse the repository at this point in the history
…d rfc6750
  • Loading branch information
CyExy committed Dec 8, 2015
1 parent e1f213e commit 5c2e6c0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 26 deletions.
11 changes: 8 additions & 3 deletions kong/plugins/oauth2/access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -376,16 +376,21 @@ function _M.execute(conf)
end
end

local token = retrieve_token(parse_access_token(conf))
local accessToken = parse_access_token(conf);
if not accessToken then
return responses.send_HTTP_UNAUTHORIZED({}, false, {["WWW-Authenticate"] = 'Bearer realm="service"'})
end

local token = retrieve_token(accessToken)
if not token then
return responses.send_HTTP_FORBIDDEN("Invalid authentication credentials")
return responses.send_HTTP_UNAUTHORIZED({[ERROR] = "invalid_token", error_description = "The access token is invalid"}, false, {["WWW-Authenticate"] = 'Bearer realm="service" error="invalid_token" error_description="The access token is invalid"'})
end

-- Check expiration date
if token.expires_in > 0 then -- zero means the token never expires
local now = timestamp.get_utc()
if now - token.created_at > (token.expires_in * 1000) then
return responses.send_HTTP_BAD_REQUEST({[ERROR] = "invalid_request", error_description = "access_token expired"})
return responses.send_HTTP_UNAUTHORIZED({[ERROR] = "invalid_token", error_description = "The access token expired"}, false, {["WWW-Authenticate"] = 'Bearer realm="service" error="invalid_token" error_description="The access token expired"'})
end
end

Expand Down
64 changes: 41 additions & 23 deletions spec/plugins/oauth2/access_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -648,21 +648,6 @@ describe("Authentication Plugin", function()
end)

describe("Making a request", function()

it("should return an error when nothing is being sent", function()
local response, status = http_client.post(STUB_GET_URL, { }, {host = "oauth2.com"})
local body = cjson.decode(response)
assert.are.equal(403, status)
assert.are.equal("Invalid authentication credentials", body.message)
end)

it("should return an error when a wrong access token is being sent", function()
local response, status = http_client.get(STUB_GET_URL, { access_token = "hello" }, {host = "oauth2.com"})
local body = cjson.decode(response)
assert.are.equal(403, status)
assert.are.equal("Invalid authentication credentials", body.message)
end)

it("should work when a correct access_token is being sent in the querystring", function()
local token = provision_token()
local _, status = http_client.post(STUB_GET_URL, { access_token = token.access_token }, {host = "oauth2.com"})
Expand Down Expand Up @@ -694,15 +679,50 @@ describe("Authentication Plugin", function()
assert.are.equal("userid123", body.headers["x-authenticated-userid"])
assert.are.equal("email", body.headers["x-authenticated-scope"])
end)
end)

describe("Authentication challenge", function()
it("should return 401 Unauthorized without error if it lacks any authentication information", function()
local response, status, headers = http_client.post(STUB_GET_URL, { }, {host = "oauth2.com"})
local body = cjson.decode(response)
assert.are.equal(401, status)
assert.are.equal('Bearer realm="service"', headers['www-authenticate'])
assert.are.equal(0, utils.table_size(body))
end)

it("should not work when a correct access_token is being sent in an authorization header (bearer)", function()
it("should return 401 Unauthorized when a invalid access token is being sent via url parameter", function()
local response, status, headers = http_client.get(STUB_GET_URL, { access_token = "invalid" }, {host = "oauth2.com"})
local body = cjson.decode(response)
assert.are.equal(401, status)
assert.are.equal('Bearer realm="service" error="invalid_token" error_description="The access token invalid"', headers['www-authenticate'])
assert.are.equal("invalid_token", body.error)
assert.are.equal("The access token invalid", body.error_description)
end)

it("should return 401 Unauthorized when a invalid access_token is being sent via the Authorization header", function()
local token = provision_token()
local response, status = http_client.post(STUB_POST_URL, { }, {host = "oauth2.com", authorization = "bearer "..token.access_token.."hello"})
local response, status, headers = http_client.post(STUB_POST_URL, { }, {host = "oauth2.com", authorization = "bearer invalid"})
local body = cjson.decode(response)
assert.are.equal(403, status)
assert.are.equal("Invalid authentication credentials", body.message)
assert.are.equal(401, status)
assert.are.equal('Bearer realm="service" error="invalid_token" error_description="The access token invalid"', headers['www-authenticate'])
assert.are.equal("invalid_token", body.error)
assert.are.equal("The access token invalid", body.error_description)
end)

it("should return 401 Unauthorized when token has expired", function()
local token = provision_token()

-- Token expires in (5 seconds)
os.execute("sleep "..tonumber(6))

local response, status, headers = http_client.post(STUB_POST_URL, { }, {host = "oauth2.com", authorization = "bearer "..token.access_token})
local body = cjson.decode(response)
assert.are.equal(401, status)
assert.are.equal(2, utils.table_size(body))
assert.are.equal('Bearer realm="service" error="invalid_token" error_description="The access token expired"', headers['www-authenticate'])
assert.are.equal("invalid_token", body.error)
assert.are.equal("The access token expired", body.error_description)
end)
end)

describe("Refresh Token", function()
Expand Down Expand Up @@ -741,10 +761,8 @@ describe("Authentication Plugin", function()

local response, status = http_client.post(STUB_POST_URL, { }, {host = "oauth2.com", authorization = "bearer "..token.access_token})
local body = cjson.decode(response)
assert.are.equal(400, status)
assert.are.equal(2, utils.table_size(body))
assert.are.equal("invalid_request", body.error)
assert.are.equal("access_token expired", body.error_description)
assert.are.equal(401, status)
assert.are.equal("The access token expired", body.error_description)

-- Refreshing the token
local response, status = http_client.post(PROXY_SSL_URL.."/oauth2/token", { refresh_token = token.refresh_token, client_id = "clientid123", client_secret = "secret123", grant_type = "refresh_token" }, {host = "oauth2.com"})
Expand Down

0 comments on commit 5c2e6c0

Please sign in to comment.