Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Base64 JWT secrets #1

Merged
merged 1 commit into from
Jan 7, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion kong/plugins/jwt/access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,13 @@ function _M.execute(conf)
return responses.send_HTTP_FORBIDDEN("No credentials found for given '"..conf.secret_key_field.."'")
end

local jwt_secret_value = jwt_secret.secret
if conf.secret_is_base64 then
jwt_secret_value = jwt:b64_decode(jwt_secret_value)
end

-- Now verify the JWT signature
if not jwt:verify_signature(jwt_secret.secret) then
if not jwt:verify_signature(jwt_secret_value) then
return responses.send_HTTP_FORBIDDEN("Invalid signature")
end

Expand Down
4 changes: 4 additions & 0 deletions kong/plugins/jwt/jwt_parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ function _M:verify_signature(key)
return alg_verify[self.header.alg](self.header_64.."."..self.claims_64, self.signature, key)
end

function _M:b64_decode(input)
return b64_decode(input)
end

--- Registered claims according to RFC 7519 Section 4.1
local registered_claims = {
["nbf"] = {
Expand Down
1 change: 1 addition & 0 deletions kong/plugins/jwt/schema.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ return {
fields = {
uri_param_names = {type = "array", default = {"jwt"}},
secret_key_field = {type = "string", default = "iss"},
secret_is_base64 = {type = "boolean", default = false},
claims_to_verify = {type = "array", enum = {"exp", "nbf"}}
}
}
32 changes: 27 additions & 5 deletions spec/plugins/jwt/access_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ local spec_helper = require "spec.spec_helpers"
local http_client = require "kong.tools.http_client"
local json = require "cjson"
local jwt_encoder = require "kong.plugins.jwt.jwt_parser"
local base64 = require "base64"

local STUB_GET_URL = spec_helper.STUB_GET_URL

Expand All @@ -13,7 +14,7 @@ local PAYLOAD = {
}

describe("JWT access", function()
local jwt_secret
local jwt_secret, base64_jwt_secret

setup(function()
spec_helper.prepare_db()
Expand All @@ -22,23 +23,28 @@ describe("JWT access", function()
{name = "tests-jwt", request_host = "jwt.com", upstream_url = "http://mockbin.com"},
{name = "tests-jwt2", request_host = "jwt2.com", upstream_url = "http://mockbin.com"},
{name = "tests-jwt3", request_host = "jwt3.com", upstream_url = "http://mockbin.com"},
{name = "tests-jwt4", request_host = "jwt4.com", upstream_url = "http://mockbin.com"}
{name = "tests-jwt4", request_host = "jwt4.com", upstream_url = "http://mockbin.com"},
{name = "tests-jwt5", request_host = "jwt5.com", upstream_url = "http://mockbin.com"}
},
consumer = {
{username = "jwt_tests_consumer"}
{username = "jwt_tests_consumer"},
{username = "jwt_tests_base64_consumer"}
},
plugin = {
{name = "jwt", config = {}, __api = 1},
{name = "jwt", config = {uri_param_names = {"token", "jwt"}}, __api = 2},
{name = "jwt", config = {claims_to_verify = {"nbf", "exp"}}, __api = 3},
{name = "jwt", config = {secret_key_field = "aud"}, __api = 4}
{name = "jwt", config = {secret_key_field = "aud"}, __api = 4},
{name = "jwt", config = {secret_is_base64 = true}, __api = 5}
},
jwt_secret = {
{__consumer = 1}
{__consumer = 1},
{__consumer = 2}
}
}

jwt_secret = fixtures.jwt_secret[1]
base64_jwt_secret = fixtures.jwt_secret[2]
spec_helper.start_kong()
end)

Expand Down Expand Up @@ -102,6 +108,22 @@ describe("JWT access", function()
assert.equal("jwt_tests_consumer", body.headers["x-consumer-username"])
end)

it("should proxy the request if secret is base64", function()
PAYLOAD.iss = base64_jwt_secret.key
local original_secret = base64_jwt_secret.secret
local base64_secret = base64.encode(base64_jwt_secret.secret)
local base_url = spec_helper.API_URL.."/consumers/jwt_tests_consumer/jwt/"..base64_jwt_secret.id
http_client.patch(base_url, {key = base64_jwt_secret.key, secret = base64_secret})

local jwt = jwt_encoder.encode(PAYLOAD, original_secret)
local authorization = "Bearer "..jwt
local response, status = http_client.get(STUB_GET_URL, nil, {host = "jwt5.com", authorization = authorization})
assert.equal(200, status)
local body = json.decode(response)
assert.equal(authorization, body.headers.authorization)
assert.equal("jwt_tests_consumer", body.headers["x-consumer-username"])
end)

it("should find the JWT if given in URL parameters", function()
PAYLOAD.iss = jwt_secret.key
local jwt = jwt_encoder.encode(PAYLOAD, jwt_secret.secret)
Expand Down