Merge pull request #8867 from lafirest/fix/jwt_exp_v5

fix(jwt): support non-integer timestamp claims
This commit is contained in:
lafirest 2022-09-02 17:15:25 +08:00 committed by GitHub
commit cffdcb4284
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 15 deletions

View File

@ -3,6 +3,7 @@
## Bug fixes
* Fix exhook `client.authorize` never being execauted. [#8780](https://github.com/emqx/emqx/pull/8780)
* Fix JWT plugin don't support non-integer timestamp claims. [#8867](https://github.com/emqx/emqx/pull/8867)
## Enhancements

View File

@ -383,7 +383,7 @@ do_verify(JWT, [JWK | More], VerifyClaims) ->
try jose_jws:verify(JWK, JWT) of
{true, Payload, _JWT} ->
Claims0 = emqx_json:decode(Payload, [return_maps]),
Claims = try_convert_to_int(Claims0, [<<"exp">>, <<"iat">>, <<"nbf">>]),
Claims = try_convert_to_num(Claims0, [<<"exp">>, <<"iat">>, <<"nbf">>]),
case verify_claims(Claims, VerifyClaims) of
ok ->
{ok, Claims};
@ -403,37 +403,37 @@ verify_claims(Claims, VerifyClaims0) ->
VerifyClaims =
[
{<<"exp">>, fun(ExpireTime) ->
is_integer(ExpireTime) andalso Now < ExpireTime
is_number(ExpireTime) andalso Now < ExpireTime
end},
{<<"iat">>, fun(IssueAt) ->
is_integer(IssueAt) andalso IssueAt =< Now
is_number(IssueAt) andalso IssueAt =< Now
end},
{<<"nbf">>, fun(NotBefore) ->
is_integer(NotBefore) andalso NotBefore =< Now
is_number(NotBefore) andalso NotBefore =< Now
end}
] ++ VerifyClaims0,
do_verify_claims(Claims, VerifyClaims).
try_convert_to_int(Claims, [Name | Names]) ->
try_convert_to_num(Claims, [Name | Names]) ->
case Claims of
#{Name := Value} ->
case Value of
Int when is_integer(Int) ->
try_convert_to_int(Claims#{Name => Int}, Names);
Int when is_number(Int) ->
try_convert_to_num(Claims#{Name => Int}, Names);
Bin when is_binary(Bin) ->
case string:to_integer(Bin) of
{Int, <<>>} ->
try_convert_to_int(Claims#{Name => Int}, Names);
case binary_to_number(Bin) of
{ok, Num} ->
try_convert_to_num(Claims#{Name => Num}, Names);
_ ->
try_convert_to_int(Claims, Names)
try_convert_to_num(Claims, Names)
end;
_ ->
try_convert_to_int(Claims, Names)
try_convert_to_num(Claims, Names)
end;
_ ->
try_convert_to_int(Claims, Names)
try_convert_to_num(Claims, Names)
end;
try_convert_to_int(Claims, []) ->
try_convert_to_num(Claims, []) ->
Claims.
do_verify_claims(_Claims, []) ->
@ -519,3 +519,16 @@ to_binary(B) when is_binary(B) ->
B.
sc(Type, Meta) -> hoconsc:mk(Type, Meta).
binary_to_number(Bin) ->
try
{ok, erlang:binary_to_integer(Bin)}
catch
_:_ ->
try
{ok, erlang:binary_to_float(Bin)}
catch
_:_ ->
false
end
end.

View File

@ -408,7 +408,19 @@ t_verify_claims(_) ->
},
?assertMatch(
{ok, #{is_superuser := false}}, emqx_authn_jwt:authenticate(Credential4, State1)
).
),
Payload5 = #{
<<"username">> => <<"myuser">>,
<<"foo">> => <<"myuser">>,
<<"exp">> => erlang:system_time(second) + 10.5
},
JWS5 = generate_jws('hmac-based', Payload5, Secret),
Credential5 = #{
username => <<"myuser">>,
password => JWS5
},
?assertMatch({ok, #{is_superuser := false}}, emqx_authn_jwt:authenticate(Credential5, State1)).
t_jwt_not_allow_empty_claim_name(_) ->
Request = #{