JWT: updated to make JWT algorithm support more flexible, and simple to extend with specific algorithm.
This commit is contained in:
@@ -64,14 +64,16 @@ feature -- Conversion
|
|||||||
|
|
||||||
encoded_string (a_secret: READABLE_STRING_8): STRING
|
encoded_string (a_secret: READABLE_STRING_8): STRING
|
||||||
local
|
local
|
||||||
alg, sign: READABLE_STRING_8
|
sign, alg_name: READABLE_STRING_8
|
||||||
|
alg: JWT_ALG
|
||||||
l_enc_payload, l_enc_header: READABLE_STRING_8
|
l_enc_payload, l_enc_header: READABLE_STRING_8
|
||||||
do
|
do
|
||||||
reset_error
|
reset_error
|
||||||
alg := header.algorithm
|
alg_name := header.algorithm
|
||||||
if not is_supporting_signature_algorithm (alg) then
|
alg := algorithms [alg_name]
|
||||||
report_unsupported_alg_error (alg)
|
if alg = Void then
|
||||||
alg := alg_hs256 -- Default ...
|
report_unsupported_alg_error (alg_name)
|
||||||
|
alg := algorithms.hs256 -- Default ...
|
||||||
end
|
end
|
||||||
l_enc_header := base64url_encode (header.string)
|
l_enc_header := base64url_encode (header.string)
|
||||||
l_enc_payload := base64url_encode (claimset.string)
|
l_enc_payload := base64url_encode (claimset.string)
|
||||||
@@ -94,12 +96,12 @@ feature -- Element change
|
|||||||
|
|
||||||
set_algorithm_to_hs256
|
set_algorithm_to_hs256
|
||||||
do
|
do
|
||||||
set_algorithm (alg_hs256)
|
set_algorithm (algorithms.hs256.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
set_algorithm_to_none
|
set_algorithm_to_none
|
||||||
do
|
do
|
||||||
set_algorithm (alg_none)
|
set_algorithm (algorithms.none.name)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,12 +16,15 @@ feature {NONE} -- Initialization
|
|||||||
|
|
||||||
default_create
|
default_create
|
||||||
do
|
do
|
||||||
|
create algorithms
|
||||||
create header
|
create header
|
||||||
create claimset
|
create claimset
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
|
algorithms: JWT_ALGORITHMS
|
||||||
|
|
||||||
header: JWT_HEADER
|
header: JWT_HEADER
|
||||||
|
|
||||||
claimset: JWT_CLAIMSET
|
claimset: JWT_CLAIMSET
|
||||||
@@ -91,6 +94,11 @@ feature -- status report
|
|||||||
Result := attached errors as errs and then across errs as ic some attached {JWT_UNSUPPORTED_ALG_ERROR} ic.item end
|
Result := attached errors as errs and then across errs as ic some attached {JWT_UNSUPPORTED_ALG_ERROR} ic.item end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
has_mismatched_alg_error: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := attached errors as errs and then across errs as ic some attached {JWT_MISMATCHED_ALG_ERROR} ic.item end
|
||||||
|
end
|
||||||
|
|
||||||
has_unverified_token_error: BOOLEAN
|
has_unverified_token_error: BOOLEAN
|
||||||
do
|
do
|
||||||
Result := attached errors as errs and then across errs as ic some attached {JWT_UNVERIFIED_TOKEN_ERROR} ic.item end
|
Result := attached errors as errs and then across errs as ic some attached {JWT_UNVERIFIED_TOKEN_ERROR} ic.item end
|
||||||
|
|||||||
27
library/security/jwt/src/jwt_alg.e
Normal file
27
library/security/jwt/src/jwt_alg.e
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {JWT_ALG}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
JWT_ALG
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: READABLE_STRING_8
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
encoded_string (a_message: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_none: BOOLEAN
|
||||||
|
-- Is Current algorithm is "none" ?
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
57
library/security/jwt/src/jwt_alg_hs256.e
Normal file
57
library/security/jwt/src/jwt_alg_hs256.e
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {JWT_ALG_HS256}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
JWT_ALG_HS256
|
||||||
|
|
||||||
|
inherit
|
||||||
|
JWT_ALG
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: STRING = "hs256"
|
||||||
|
|
||||||
|
encoded_string (a_message: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING
|
||||||
|
do
|
||||||
|
Result := base64_hmacsha256 (a_message, a_secret)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
base64_hmacsha256 (s: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING_8
|
||||||
|
local
|
||||||
|
hs256: HMAC_SHA256
|
||||||
|
do
|
||||||
|
create hs256.make_ascii_key (a_secret)
|
||||||
|
hs256.update_from_string (s)
|
||||||
|
-- if Version >= EiffelStudio 18.01 then
|
||||||
|
-- Result := hs256.base64_digest --lowercase_hexadecimal_string_digest
|
||||||
|
-- else
|
||||||
|
Result := base64_bytes_encoded_string (hs256.digest)
|
||||||
|
-- end
|
||||||
|
end
|
||||||
|
|
||||||
|
base64_bytes_encoded_string (a_bytes: SPECIAL [NATURAL_8]): STRING_8
|
||||||
|
-- Base64 string from `a_bytes`.
|
||||||
|
--| Note: to be removed when 18.01 is not latest release anymore.
|
||||||
|
local
|
||||||
|
s: STRING
|
||||||
|
i,n: INTEGER
|
||||||
|
do
|
||||||
|
from
|
||||||
|
i := 1
|
||||||
|
n := a_bytes.count
|
||||||
|
create s.make (n)
|
||||||
|
until
|
||||||
|
i > n
|
||||||
|
loop
|
||||||
|
s.append_code (a_bytes[i - 1])
|
||||||
|
i := i + 1
|
||||||
|
end
|
||||||
|
Result := (create {BASE64}).encoded_string (s)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
30
library/security/jwt/src/jwt_alg_none.e
Normal file
30
library/security/jwt/src/jwt_alg_none.e
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {JWT_ALG_NONE}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
JWT_ALG_NONE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
JWT_ALG
|
||||||
|
redefine
|
||||||
|
is_none
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: STRING = "none"
|
||||||
|
|
||||||
|
encoded_string (a_message: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING
|
||||||
|
do
|
||||||
|
create Result.make_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_none: BOOLEAN = True
|
||||||
|
-- Is Current algorithm is "none" ?
|
||||||
|
|
||||||
|
end
|
||||||
98
library/security/jwt/src/jwt_algorithms.e
Normal file
98
library/security/jwt/src/jwt_algorithms.e
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {JWT_ALGORITHMS}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
JWT_ALGORITHMS
|
||||||
|
|
||||||
|
inherit
|
||||||
|
ANY
|
||||||
|
redefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
|
create
|
||||||
|
default_create
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
default_create
|
||||||
|
do
|
||||||
|
create items.make_caseless (2)
|
||||||
|
register_algorithm (hs256)
|
||||||
|
register_algorithm (none)
|
||||||
|
-- TODO: check if this is acceptable default.
|
||||||
|
set_default_algorithm ({JWT_ALG_HS256}.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
hs256: JWT_ALG_HS256
|
||||||
|
do
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
none: JWT_ALG_NONE
|
||||||
|
do
|
||||||
|
create Result
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
default_algorithm: JWT_ALG
|
||||||
|
do
|
||||||
|
if attached internal_default_alg_name as l_alg_name then
|
||||||
|
Result := algorithm (l_alg_name)
|
||||||
|
end
|
||||||
|
if Result = Void then
|
||||||
|
Result := none
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
algorithm alias "[]" (a_name: READABLE_STRING_GENERAL): detachable JWT_ALG
|
||||||
|
do
|
||||||
|
Result := items [a_name]
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Element change
|
||||||
|
|
||||||
|
register_algorithm (alg: attached like algorithm)
|
||||||
|
do
|
||||||
|
items [alg.name] := alg
|
||||||
|
end
|
||||||
|
|
||||||
|
unregister_algorithm (a_alg_name: READABLE_STRING_GENERAL)
|
||||||
|
do
|
||||||
|
items.remove (a_alg_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
set_default_algorithm (a_alg_name: detachable READABLE_STRING_GENERAL)
|
||||||
|
do
|
||||||
|
if
|
||||||
|
a_alg_name = Void or else
|
||||||
|
not is_supported_algorithm (a_alg_name)
|
||||||
|
then
|
||||||
|
internal_default_alg_name := Void
|
||||||
|
else
|
||||||
|
internal_default_alg_name := a_alg_name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_supported_algorithm (a_name: READABLE_STRING_GENERAL): BOOLEAN
|
||||||
|
do
|
||||||
|
Result := items.has (a_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
items: STRING_TABLE [attached like algorithm]
|
||||||
|
|
||||||
|
internal_default_alg_name: detachable READABLE_STRING_GENERAL
|
||||||
|
|
||||||
|
invariant
|
||||||
|
|
||||||
|
end
|
||||||
@@ -9,6 +9,20 @@ class
|
|||||||
|
|
||||||
inherit
|
inherit
|
||||||
JWT_UTILITIES
|
JWT_UTILITIES
|
||||||
|
redefine
|
||||||
|
default_create
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
default_create
|
||||||
|
do
|
||||||
|
create algorithms
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Settings
|
||||||
|
|
||||||
|
algorithms: JWT_ALGORITHMS
|
||||||
|
|
||||||
feature -- Access
|
feature -- Access
|
||||||
|
|
||||||
@@ -18,11 +32,12 @@ feature -- Access
|
|||||||
-- WARNING: passing Void for `a_alg` is not safe, as the server should know which alg he used for tokens,
|
-- WARNING: passing Void for `a_alg` is not safe, as the server should know which alg he used for tokens,
|
||||||
-- leaving the possibility to use the header alg is dangerous as client may use "none" and then bypass verification!
|
-- leaving the possibility to use the header alg is dangerous as client may use "none" and then bypass verification!
|
||||||
require
|
require
|
||||||
a_valid_alg: a_alg /= Void implies is_supporting_signature_algorithm (a_alg)
|
a_valid_alg: a_alg /= Void implies algorithms.is_supported_algorithm (a_alg)
|
||||||
local
|
local
|
||||||
jws: JWS
|
jws: JWS
|
||||||
i,j,n: INTEGER
|
i,j,n: INTEGER
|
||||||
alg, l_enc_payload, l_enc_header, l_signature: READABLE_STRING_8
|
alg, l_enc_payload, l_enc_header, l_signature: READABLE_STRING_8
|
||||||
|
alg_encoder: JWT_ALG
|
||||||
do
|
do
|
||||||
n := a_token_input.count
|
n := a_token_input.count
|
||||||
i := a_token_input.index_of ('.', 1)
|
i := a_token_input.index_of ('.', 1)
|
||||||
@@ -43,17 +58,18 @@ feature -- Access
|
|||||||
else
|
else
|
||||||
if alg = Void then
|
if alg = Void then
|
||||||
-- Use default
|
-- Use default
|
||||||
alg := alg_hs256
|
alg := algorithms.default_algorithm.name
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
jws.set_algorithm (alg)
|
jws.set_algorithm (alg)
|
||||||
check alg_set: alg /= Void end
|
check alg_set: alg /= Void end
|
||||||
if ctx = Void or else not ctx.validation_ignored then
|
if ctx = Void or else not ctx.validation_ignored then
|
||||||
if not is_supporting_signature_algorithm (alg) then
|
alg_encoder := algorithms [alg]
|
||||||
|
if alg_encoder = Void then
|
||||||
jws.report_unsupported_alg_error (alg)
|
jws.report_unsupported_alg_error (alg)
|
||||||
alg := alg_hs256
|
alg_encoder := algorithms.default_algorithm
|
||||||
end
|
end
|
||||||
if not l_signature.same_string (signature (l_enc_header, l_enc_payload, a_verification_key, alg)) then
|
if not l_signature.same_string (signature (l_enc_header, l_enc_payload, a_verification_key, alg_encoder)) then
|
||||||
jws.report_unverified_token_error
|
jws.report_unverified_token_error
|
||||||
end
|
end
|
||||||
if
|
if
|
||||||
|
|||||||
@@ -7,14 +7,6 @@ note
|
|||||||
class
|
class
|
||||||
JWT_UTILITIES
|
JWT_UTILITIES
|
||||||
|
|
||||||
feature -- Constants
|
|
||||||
|
|
||||||
alg_hs256: STRING = "HS256"
|
|
||||||
-- HMAC SHA256.
|
|
||||||
|
|
||||||
alg_none: STRING = "none"
|
|
||||||
-- for unsecured token.
|
|
||||||
|
|
||||||
feature -- Encoding
|
feature -- Encoding
|
||||||
|
|
||||||
base64url_encode (s: READABLE_STRING_8): STRING_8
|
base64url_encode (s: READABLE_STRING_8): STRING_8
|
||||||
@@ -35,61 +27,21 @@ feature -- Encoding
|
|||||||
Result.replace_substring_all ("/", "_")
|
Result.replace_substring_all ("/", "_")
|
||||||
end
|
end
|
||||||
|
|
||||||
signature (a_enc_header, a_enc_payload: READABLE_STRING_8; a_secret: READABLE_STRING_8; alg: READABLE_STRING_8): STRING_8
|
signature (a_enc_header, a_enc_payload: READABLE_STRING_8; a_secret: READABLE_STRING_8; alg: JWT_ALG): STRING_8
|
||||||
local
|
local
|
||||||
s: STRING
|
s: STRING
|
||||||
do
|
do
|
||||||
if alg.is_case_insensitive_equal (alg_none) then
|
if alg.is_none then
|
||||||
create Result.make_empty
|
create Result.make_empty
|
||||||
else
|
else
|
||||||
create s.make (a_enc_header.count + 1 + a_enc_payload.count)
|
create s.make (a_enc_header.count + 1 + a_enc_payload.count)
|
||||||
s.append (a_enc_header)
|
s.append (a_enc_header)
|
||||||
s.append_character ('.')
|
s.append_character ('.')
|
||||||
s.append (a_enc_payload)
|
s.append (a_enc_payload)
|
||||||
if alg.is_case_insensitive_equal (alg_hs256) then
|
Result := urlsafe_encode (alg.encoded_string (s, a_secret))
|
||||||
Result := base64_hmacsha256 (s, a_secret)
|
|
||||||
else
|
|
||||||
Result := base64_hmacsha256 (s, a_secret)
|
|
||||||
end
|
|
||||||
Result := urlsafe_encode (Result)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
base64_hmacsha256 (s: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING_8
|
|
||||||
local
|
|
||||||
hs256: HMAC_SHA256
|
|
||||||
do
|
|
||||||
create hs256.make_ascii_key (a_secret)
|
|
||||||
hs256.update_from_string (s)
|
|
||||||
-- if Version >= EiffelStudio 17.11 then
|
|
||||||
-- Result := hs256.base64_digest --lowercase_hexadecimal_string_digest
|
|
||||||
-- else
|
|
||||||
Result := base64_bytes_encoded_string (hs256.digest)
|
|
||||||
-- end
|
|
||||||
end
|
|
||||||
|
|
||||||
feature {NONE} -- Implementation
|
|
||||||
|
|
||||||
base64_bytes_encoded_string (a_bytes: SPECIAL [NATURAL_8]): STRING_8
|
|
||||||
-- Base64 string from `a_bytes`.
|
|
||||||
--| Note: to be removed when 17.11 is not latest release anymore.
|
|
||||||
local
|
|
||||||
s: STRING
|
|
||||||
i,n: INTEGER
|
|
||||||
do
|
|
||||||
from
|
|
||||||
i := 1
|
|
||||||
n := a_bytes.count
|
|
||||||
create s.make (n)
|
|
||||||
until
|
|
||||||
i > n
|
|
||||||
loop
|
|
||||||
s.append_code (a_bytes[i - 1])
|
|
||||||
i := i + 1
|
|
||||||
end
|
|
||||||
Result := (create {BASE64}).encoded_string (s)
|
|
||||||
end
|
|
||||||
|
|
||||||
feature -- Decoding
|
feature -- Decoding
|
||||||
|
|
||||||
base64url_decode (s: READABLE_STRING_8): STRING_8
|
base64url_decode (s: READABLE_STRING_8): STRING_8
|
||||||
@@ -119,20 +71,4 @@ feature -- Decoding
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
feature -- Signature
|
|
||||||
|
|
||||||
supported_signature_algorithms: LIST [READABLE_STRING_8]
|
|
||||||
-- Supported signature algorithm `alg`?
|
|
||||||
do
|
|
||||||
create {ARRAYED_LIST [READABLE_STRING_8]} Result.make (2)
|
|
||||||
Result.extend (alg_hs256)
|
|
||||||
Result.extend (alg_none)
|
|
||||||
end
|
|
||||||
|
|
||||||
is_supporting_signature_algorithm (alg: READABLE_STRING_8): BOOLEAN
|
|
||||||
-- Is supporting signature algorithm `alg`?
|
|
||||||
do
|
|
||||||
Result := across supported_signature_algorithms as ic some alg.is_case_insensitive_equal (ic.item) end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
22
library/security/jwt/testing/jwt_alg_test.e
Normal file
22
library/security/jwt/testing/jwt_alg_test.e
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {JWT_ALG_TEST}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date$"
|
||||||
|
revision: "$Revision$"
|
||||||
|
|
||||||
|
class
|
||||||
|
JWT_ALG_TEST
|
||||||
|
|
||||||
|
inherit
|
||||||
|
JWT_ALG
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
name: STRING = "test"
|
||||||
|
|
||||||
|
encoded_string (a_message: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING
|
||||||
|
do
|
||||||
|
Result := "TEST<<"+ a_message + ">>"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@@ -16,6 +16,30 @@ inherit
|
|||||||
|
|
||||||
feature -- Test
|
feature -- Test
|
||||||
|
|
||||||
|
example
|
||||||
|
local
|
||||||
|
jwt: JWS
|
||||||
|
l_loader: JWT_LOADER
|
||||||
|
tok: STRING
|
||||||
|
do
|
||||||
|
create jwt.make_with_json_payload ("[
|
||||||
|
{"iss":"joe", "exp":1200819380,"http://example.com/is_root":true}
|
||||||
|
]")
|
||||||
|
jwt.set_algorithm_to_hs256
|
||||||
|
tok := jwt.encoded_string ("my-secret")
|
||||||
|
|
||||||
|
create l_loader
|
||||||
|
if
|
||||||
|
attached l_loader.token (tok, Void, "my-secret", Void) as l_tok and then
|
||||||
|
not l_tok.has_error
|
||||||
|
then
|
||||||
|
print (l_tok.claimset.string)
|
||||||
|
check verified: not l_tok.has_unverified_token_error end
|
||||||
|
check no_error: not l_tok.has_error end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
test_jwt_io
|
test_jwt_io
|
||||||
local
|
local
|
||||||
jwt: JWS
|
jwt: JWS
|
||||||
@@ -185,7 +209,8 @@ feature -- Test
|
|||||||
tok := jwt.encoded_string ("secret")
|
tok := jwt.encoded_string ("secret")
|
||||||
|
|
||||||
if attached (create {JWT_LOADER}).token (tok, "HS256", "secret", Void) as l_tok then
|
if attached (create {JWT_LOADER}).token (tok, "HS256", "secret", Void) as l_tok then
|
||||||
assert ("no error", not jwt.has_error)
|
assert ("error", l_tok.has_error)
|
||||||
|
assert ("has_mismatched_alg_error", l_tok.has_mismatched_alg_error)
|
||||||
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -205,15 +230,50 @@ feature -- Test
|
|||||||
tok := jwt.encoded_string ("secret")
|
tok := jwt.encoded_string ("secret")
|
||||||
|
|
||||||
if attached (create {JWT_LOADER}).token (tok, "none", "secret", Void) as l_tok then
|
if attached (create {JWT_LOADER}).token (tok, "none", "secret", Void) as l_tok then
|
||||||
assert ("no error", not jwt.has_error)
|
assert ("no error", not l_tok.has_error)
|
||||||
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
||||||
end
|
end
|
||||||
if attached (create {JWT_LOADER}).token (tok, Void, "secret", Void) as l_tok then
|
if attached (create {JWT_LOADER}).token (tok, Void, "secret", Void) as l_tok then
|
||||||
assert ("no error", not jwt.has_error)
|
assert ("no error", not l_tok.has_error)
|
||||||
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test_additional_alg
|
||||||
|
local
|
||||||
|
jwt: JWS
|
||||||
|
payload: STRING
|
||||||
|
tok: STRING
|
||||||
|
l_loader: JWT_LOADER
|
||||||
|
do
|
||||||
|
payload := "[
|
||||||
|
{"iss":"joe","exp":1300819380,"http://example.com/is_root":true}
|
||||||
|
]"
|
||||||
|
|
||||||
|
create jwt.make_with_json_payload (payload)
|
||||||
|
jwt.algorithms.register_algorithm (create {JWT_ALG_TEST})
|
||||||
|
jwt.set_algorithm ({JWT_ALG_TEST}.name)
|
||||||
|
tok := jwt.encoded_string ("secret")
|
||||||
|
|
||||||
|
create l_loader
|
||||||
|
l_loader.algorithms.register_algorithm (create {JWT_ALG_TEST})
|
||||||
|
if attached l_loader.token (tok, "test", "secret", Void) as l_tok then
|
||||||
|
assert ("no error", not l_tok.has_error)
|
||||||
|
assert ("not has_unsupported_alg_error", not l_tok.has_unsupported_alg_error)
|
||||||
|
assert ("same payload", l_tok.claimset.string.same_string (payload))
|
||||||
|
end
|
||||||
|
if attached l_loader.token (tok, Void, "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 l_loader
|
||||||
|
if attached l_loader.token (tok, "test", "secret", Void) as l_tok then
|
||||||
|
assert ("has error", l_tok.has_error)
|
||||||
|
assert ("has_unsupported_alg_error", l_tok.has_unsupported_alg_error)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Implementation
|
feature -- Implementation
|
||||||
|
|
||||||
duplicated_time (dt: DATE_TIME): DATE_TIME
|
duplicated_time (dt: DATE_TIME): DATE_TIME
|
||||||
|
|||||||
Reference in New Issue
Block a user