329 lines
12 KiB
Lua
329 lines
12 KiB
Lua
local jwt_parser = require "kong.plugins.jwt.jwt_parser"
|
|
local fixtures = require "spec.03-plugins.16-jwt.fixtures"
|
|
|
|
|
|
describe("Plugin: jwt (parser)", function()
|
|
describe("Encoding", function()
|
|
it("should properly encode using HS256", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "1234567890",
|
|
name = "John Doe",
|
|
admin = true
|
|
}, "secret")
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature("secret"))
|
|
end)
|
|
it("should properly encode using HS384", function()
|
|
local token = jwt_parser.encode({
|
|
name = "John Doe",
|
|
admin = true,
|
|
sub = "1234567890"
|
|
}, "secret", "HS384")
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature("secret"))
|
|
end)
|
|
it("should properly encode using HS512", function()
|
|
local token = jwt_parser.encode({
|
|
name = "John Doe",
|
|
admin = true,
|
|
sub = "1234567890"
|
|
}, "secret", "HS512")
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature("secret"))
|
|
end)
|
|
it("should properly encode using RS256", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "1234567890",
|
|
name = "John Doe",
|
|
admin = true
|
|
}, fixtures.rs256_private_key, "RS256")
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.rs256_public_key))
|
|
end)
|
|
it("should properly encode using RS384", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "1234567890",
|
|
name = "John Doe",
|
|
admin = true
|
|
}, fixtures.rs384_private_key, "RS384")
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.rs384_public_key))
|
|
end)
|
|
it("should encode using RS512", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "1234567890",
|
|
name = "John Doe",
|
|
admin = true,
|
|
}, fixtures.rs512_private_key, "RS512")
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.rs512_public_key))
|
|
end)
|
|
|
|
it("should encode using ES256", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.es256_private_key, 'ES256')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.es256_public_key))
|
|
end)
|
|
|
|
it("should encode using ES384", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.es384_private_key, 'ES384')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.es384_public_key))
|
|
end)
|
|
|
|
it("should encode using ES512", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.es512_private_key, 'ES512')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.es512_public_key))
|
|
end)
|
|
it("should encode using PS256", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.ps256_private_key, 'PS256')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ps256_public_key))
|
|
end)
|
|
|
|
it("should encode using PS384", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.ps384_private_key, 'PS384')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ps384_public_key))
|
|
end)
|
|
|
|
it("should encode using PS512", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.ps512_private_key, 'PS512')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ps512_public_key))
|
|
end)
|
|
|
|
it("should encode using EdDSA with Ed25519 key", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.ed25519_private_key, 'EdDSA')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ed25519_public_key))
|
|
end)
|
|
|
|
it("should encode using EdDSA with Ed448 key", function()
|
|
local token = jwt_parser.encode({
|
|
sub = "5656565656",
|
|
name = "Jane Doe",
|
|
admin = true
|
|
}, fixtures.ed448_private_key, 'EdDSA')
|
|
|
|
assert.truthy(token)
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ed448_public_key))
|
|
end)
|
|
|
|
end)
|
|
describe("Decoding", function()
|
|
it("throws an error if not given a string", function()
|
|
assert.has_error(function()
|
|
jwt_parser:new()
|
|
end, "Token must be a string, got nil")
|
|
end)
|
|
it("refuses invalid alg", function()
|
|
local token = jwt_parser.encode({sub = "1234"}, "secret", nil, {
|
|
typ = "JWT",
|
|
alg = "foo"
|
|
})
|
|
local _, err = jwt_parser:new(token)
|
|
assert.equal("invalid alg", err)
|
|
end)
|
|
it("accepts a valid encoding request", function()
|
|
local token = jwt_parser.encode({sub = "1234"}, "secret", nil, {
|
|
typ = "JWT",
|
|
alg = "RS256"
|
|
})
|
|
assert(jwt_parser:new(token))
|
|
end)
|
|
it("accepts a valid encoding request with lowercase TYP", function()
|
|
local token = jwt_parser.encode({sub = "1234"}, "secret", nil, {
|
|
typ = "jwt",
|
|
alg = "RS256"
|
|
})
|
|
assert(jwt_parser:new(token))
|
|
end)
|
|
it("accepts a valid encoding request with missing TYP", function()
|
|
local token = jwt_parser.encode({sub = "1234"}, "secret", nil, {alg = "RS256"})
|
|
assert(jwt_parser:new(token))
|
|
end)
|
|
end)
|
|
describe("verify signature", function()
|
|
it("using HS256", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, "secret")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature("secret"))
|
|
assert.False(jwt:verify_signature("invalid"))
|
|
end)
|
|
it("using HS384", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, "secret", "HS384")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature("secret"))
|
|
assert.False(jwt:verify_signature("invalid"))
|
|
end)
|
|
it("using HS512", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, "secret", "HS512")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature("secret"))
|
|
assert.False(jwt:verify_signature("invalid"))
|
|
end)
|
|
it("using RS256", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.rs256_private_key, 'RS256')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.rs256_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.rs384_public_key))
|
|
end)
|
|
it("using RS384", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.rs384_private_key, "RS384")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.rs384_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.rs512_public_key))
|
|
end)
|
|
it("using RS512", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.rs512_private_key, 'RS512')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.rs512_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.rs256_public_key))
|
|
end)
|
|
it("using ES256", function()
|
|
for _ = 1, 500 do
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.es256_private_key, 'ES256')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.es256_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.rs256_public_key))
|
|
end
|
|
end)
|
|
it("using ES384", function()
|
|
for _ = 1, 500 do
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.es384_private_key, 'ES384')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.es384_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.rs256_public_key))
|
|
end
|
|
end)
|
|
it("using ES512", function()
|
|
for _ = 1, 500 do
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.es512_private_key, 'ES512')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.es512_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.rs256_public_key))
|
|
end
|
|
end)
|
|
it("using PS256", function()
|
|
for _ = 1, 500 do
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.ps256_private_key, 'PS256')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ps256_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.es256_public_key))
|
|
end
|
|
end)
|
|
it("using PS384", function()
|
|
for _ = 1, 500 do
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.ps384_private_key, 'PS384')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ps384_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.es256_public_key))
|
|
end
|
|
end)
|
|
it("using PS512", function()
|
|
for _ = 1, 500 do
|
|
local token = jwt_parser.encode({sub = "foo"}, fixtures.ps512_private_key, 'PS512')
|
|
local jwt = assert(jwt_parser:new(token))
|
|
assert.True(jwt:verify_signature(fixtures.ps512_public_key))
|
|
assert.False(jwt:verify_signature(fixtures.es256_public_key))
|
|
end
|
|
end)
|
|
end)
|
|
describe("verify registered claims", function()
|
|
it("requires claims passed as arguments", function()
|
|
local token = jwt_parser.encode({sub = "foo"}, "secret")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
|
|
local ok, errors = jwt:verify_registered_claims({"exp", "nbf"})
|
|
assert.False(ok)
|
|
assert.same({exp = "must be a number", nbf = "must be a number"}, errors)
|
|
|
|
ok, errors = jwt:verify_registered_claims({"nbf"})
|
|
assert.False(ok)
|
|
assert.same({nbf = "must be a number"}, errors)
|
|
end)
|
|
it("checks the type of given registered claims", function()
|
|
local token = jwt_parser.encode({exp = "bar", nbf = "foo"}, "secret")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
|
|
local ok, errors = jwt:verify_registered_claims({"exp", "nbf"})
|
|
assert.False(ok)
|
|
assert.same({exp = "must be a number", nbf = "must be a number"}, errors)
|
|
end)
|
|
it("checks the exp claim", function()
|
|
local token = jwt_parser.encode({exp = os.time() - 10}, "secret")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
|
|
ngx.update_time()
|
|
local ok, errors = jwt:verify_registered_claims({"exp"})
|
|
assert.False(ok)
|
|
assert.same({exp = "token expired"}, errors)
|
|
end)
|
|
it("checks the nbf claim", function()
|
|
local token = jwt_parser.encode({nbf = os.time() + 10}, "secret")
|
|
local jwt = assert(jwt_parser:new(token))
|
|
|
|
local ok, errors = jwt:verify_registered_claims({"nbf"})
|
|
assert.False(ok)
|
|
assert.same({nbf = "token not valid yet"}, errors)
|
|
end)
|
|
end)
|
|
end)
|