Updated JWT library, add supports for claim exp, iat, nbf, iss, aud .

This commit is contained in:
Jocelyn Fiat
2017-06-07 23:24:46 +02:00
parent 40cbe7dfc9
commit 7e54825b84
18 changed files with 1429 additions and 246 deletions

View File

@@ -9,71 +9,185 @@ class
inherit
EQA_TEST_SET
SHARED_EXECUTION_ENVIRONMENT
undefine
default_create
end
feature -- Test
test_jwt_io
local
jwt: JWT
header: STRING
payload: STRING
jwt: JWS
ut: JWT_UTILITIES
do
payload := "[
{"sub":"1234567890","name":"John Doe","admin":true}
]"
payload.adjust
payload.replace_substring_all ("%N", "%R%N")
create jwt
jwt.set_algorithm ("HS256")
jwt.claimset.set_subject ("1234567890")
jwt.claimset.set_claim ("name", "John Doe")
jwt.claimset.set_claim ("admin", True)
create ut
assert ("header", jwt.base64url_encode (jwt.header (Void, "HS256")).same_string ("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"))
assert ("payload", jwt.base64url_encode (payload).same_string ("eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9"))
assert ("signature", jwt.encoded_string (payload, "secret", "HS256").same_string ("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.pcHcZspUvuiqIPVB_i_qmcvCJv63KLUgIAKIlXI1gY8"))
assert ("header", ut.base64url_encode (jwt.header.string).same_string ("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"))
assert ("payload", ut.base64url_encode (jwt.claimset.string).same_string ("eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9"))
assert ("signature", jwt.encoded_string ("secret").same_string ("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.pcHcZspUvuiqIPVB_i_qmcvCJv63KLUgIAKIlXI1gY8"))
end
test_jwt
local
jwt: JWT
jwt: JWS
jwt_loader: JWT_LOADER
payload: STRING
tok: STRING
do
payload := "[
{"iss":"joe",
"exp":1300819380,
"http://example.com/is_root":true}
{"iss":"joe","exp":1300819380,"http://example.com/is_root":true}
]"
-- payload := "[
-- {"sub":"1234567890","name":"John Doe","admin":true}
-- ]"
create jwt
tok := jwt.encoded_string (payload, "secret", "HS256")
create jwt.make_with_json_payload (payload)
jwt.set_algorithm ("HS256")
tok := jwt.encoded_string ("secret")
if attached jwt.decoded_string (tok, "secret", Void) as l_tok_payload then
assert ("no error", not jwt.has_error)
assert ("same payload", l_tok_payload.same_string (payload))
create jwt_loader
if attached jwt_loader.token (tok, "secret", Void) as l_tok then
assert ("no error", not l_tok.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload))
end
end
test_jwt_with_claimset
local
jwt: JWS
jwt_loader: JWT_LOADER
payload: STRING
tok: STRING
now, dt: DATE_TIME
ctx: JWT_CONTEXT
do
-- payload := "[
-- {"iss":"joe","exp":1300819380,"http://example.com/is_root":true}
-- ]"
payload := "[
{"sub":"1234567890","name":"John Doe","admin":true}
]"
create jwt.make_with_json_payload (payload)
jwt.set_algorithm ("HS256")
create now.make_now_utc
jwt.claimset.set_issued_at (now)
dt := duplicated_time (now)
dt.minute_add (60)
jwt.claimset.set_expiration_time (dt)
jwt.claimset.set_issuer ("urn:foo")
jwt.claimset.set_audience ("urn:foo")
tok := jwt.encoded_string ("secret")
payload := jwt.claimset.string
create jwt_loader
-- Test with validation + exp
if attached jwt_loader.token (tok, "secret", Void) as l_tok then
assert ("no error", not l_tok.has_error)
assert ("same payload", l_tok.claimset.string.same_string (payload))
end
create ctx
ctx.set_time (now)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error)
end
dt := duplicated_time (now)
dt.hour_add (5)
ctx.set_time (dt)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("exp error", l_tok.has_error)
end
-- Test with validation + not before
dt := duplicated_time (now)
dt.second_add (30)
jwt.claimset.set_not_before_time (dt)
tok := jwt.encoded_string ("secret")
ctx.set_time (now)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("has nbf error", l_tok.has_error)
end
dt := duplicated_time (now)
dt.second_add (15)
ctx.set_time (dt)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("has nbf error", l_tok.has_error)
end
dt := duplicated_time (now)
dt.minute_add (45)
ctx.set_time (dt)
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error)
end
-- Test Issuer
ctx.set_issuer ("urn:foobar")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("has iss error", l_tok.has_error)
end
ctx.set_issuer ("urn:foo")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error)
end
-- Test Audience
ctx.set_audience ("urn:foobar")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("has aud error", l_tok.has_error)
end
ctx.set_audience ("urn:foo")
if attached jwt_loader.token (tok, "secret", ctx) as l_tok then
assert ("no error", not l_tok.has_error)
end
end
test_unsecured_jwt
local
jwt: JWT
jwt: JWS
payload: STRING
tok: STRING
do
payload := "[
{"iss":"joe",
"exp":1300819380,
"http://example.com/is_root":true}
{"iss":"joe","exp":1300819380,"http://example.com/is_root":true}
]"
create jwt
tok := jwt.encoded_string (payload, "secret", "none")
create jwt.make_with_json_payload (payload)
jwt.set_algorithm ("none")
tok := jwt.encoded_string ("secret")
if attached jwt.decoded_string (tok, "secret", Void) as l_tok_payload then
if attached (create {JWT_LOADER}).token (tok, "secret", Void) as l_tok then
assert ("no error", not jwt.has_error)
assert ("same payload", l_tok_payload.same_string (payload))
assert ("same payload", l_tok.claimset.string.same_string (payload))
end
end
feature -- Implementation
duplicated_time (dt: DATE_TIME): DATE_TIME
do
Result := dt.deep_twin
end
end

View File

@@ -1,15 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-16-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-16-0 http://www.eiffel.com/developers/xml/configuration-1-16-0.xsd" name="testing" uuid="DB49E98A-0048-414A-A469-EE9B5B903BF3">
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-15-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-15-0 http://www.eiffel.com/developers/xml/configuration-1-15-0.xsd" name="testing" uuid="DB49E98A-0048-414A-A469-EE9B5B903BF3">
<target name="testing">
<root class="ANY" feature="default_create"/>
<setting name="console_application" value="false"/>
<capability>
<concurrency support="none"/>
<void_safety support="all"/>
</capability>
<setting name="console_application" value="true"/>
<option warning="true" void_safety="all">
</option>
<setting name="concurrency" value="none"/>
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
<library name="jwt" location="..\jwt.ecf" readonly="false"/>
<library name="jwt" location="..\jwt-safe.ecf" readonly="false"/>
<library name="testing" location="$ISE_LIBRARY\library\testing\testing.ecf"/>
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
<tests name="src" location=".\" recursive="true"/>
</target>
</system>