feat: extract attrs field from http and jwt auth response

This commit is contained in:
zmstone 2024-03-19 19:53:16 +01:00
parent f9d51484cc
commit cc4805b1ac
5 changed files with 29 additions and 13 deletions

View File

@ -1726,9 +1726,21 @@ do_authenticate(Credential, #channel{clientinfo = ClientInfo} = Channel) ->
{error, emqx_reason_codes:connack_error(Reason)}
end.
merge_auth_result(ClientInfo, AuthResult) when is_map(ClientInfo) andalso is_map(AuthResult) ->
%% Merge authentication result into ClientInfo
%% Authentication result may include:
%% 1. `is_superuser': The superuser flag from various backends
%% 2. `acl': ACL rules from JWT, HTTP auth backend
%% 3. `attrs': Extra client attributes from JWT, HTTP auth backend
merge_auth_result(ClientInfo, AuthResult0) when is_map(ClientInfo) andalso is_map(AuthResult0) ->
IsSuperuser = maps:get(is_superuser, AuthResult, false),
maps:merge(ClientInfo, AuthResult#{is_superuser => IsSuperuser}).
AuthResult = maps:without([attrs], AuthResult0),
Attrs0 = maps:get(attrs, ClientInfo, #{}),
Attrs1 = maps:get(attrs, AuthResult0, #{}),
Attrs = maps:merge(Attrs0, Attrs1),
maps:merge(
ClientInfo#{attrs => Attrs},
AuthResult#{is_superuser => IsSuperuser}
).
%%--------------------------------------------------------------------
%% Process Topic Alias

View File

@ -197,9 +197,10 @@ handle_response(Headers, Body) ->
{ok, NBody} ->
case maps:get(<<"result">>, NBody, <<"ignore">>) of
<<"allow">> ->
Res = emqx_authn_utils:is_superuser(NBody),
%% TODO: Return by user property
{ok, Res#{user_property => maps:get(<<"user_property">>, NBody, #{})}};
IsSuperuser = emqx_authn_utils:is_superuser(NBody),
Attrs = maps:get(<<"attrs">>, NBody, #{}),
Result = maps:merge(IsSuperuser, Attrs),
{ok, Result};
<<"deny">> ->
{error, not_authorized};
<<"ignore">> ->

View File

@ -533,7 +533,7 @@ samples() ->
{ok, Req, State}
end,
config_params => #{},
result => {ok, #{is_superuser => false, user_property => #{}}}
result => {ok, #{is_superuser => false, attrs => #{}}}
},
%% get request with json body response
@ -548,7 +548,7 @@ samples() ->
{ok, Req, State}
end,
config_params => #{},
result => {ok, #{is_superuser => true, user_property => #{}}}
result => {ok, #{is_superuser => true, attrs => #{}}}
},
%% get request with url-form-encoded body response
@ -566,7 +566,7 @@ samples() ->
{ok, Req, State}
end,
config_params => #{},
result => {ok, #{is_superuser => true, user_property => #{}}}
result => {ok, #{is_superuser => true, attrs => #{}}}
},
%% get request with response of unknown encoding
@ -608,7 +608,7 @@ samples() ->
<<"method">> => <<"post">>,
<<"headers">> => #{<<"content-type">> => <<"application/json">>}
},
result => {ok, #{is_superuser => false, user_property => #{}}}
result => {ok, #{is_superuser => false, attrs => #{}}}
},
%% simple post request, application/x-www-form-urlencoded
@ -634,7 +634,7 @@ samples() ->
<<"application/x-www-form-urlencoded">>
}
},
result => {ok, #{is_superuser => false, user_property => #{}}}
result => {ok, #{is_superuser => false, attrs => #{}}}
},
%% simple post request for placeholders, application/json
@ -669,7 +669,7 @@ samples() ->
<<"cert_common_name">> => ?PH_CERT_CN_NAME
}
},
result => {ok, #{is_superuser => false, user_property => #{}}}
result => {ok, #{is_superuser => false, attrs => #{}}}
},
%% custom headers

View File

@ -1,7 +1,7 @@
%% -*- mode: erlang -*-
{application, emqx_auth_jwt, [
{description, "EMQX JWT Authentication and Authorization"},
{vsn, "0.2.0"},
{vsn, "0.3.0"},
{registered, []},
{mod, {emqx_auth_jwt_app, []}},
{applications, [

View File

@ -220,7 +220,10 @@ verify(JWT, JWKs, VerifyClaims, AclClaimName) ->
case do_verify(JWT, JWKs, VerifyClaims) of
{ok, Extra} ->
try
{ok, acl(Extra, AclClaimName)}
ACL = acl(Extra, AclClaimName),
Attrs = maps:get(<<"attrs">>, Extra, #{}),
Result = maps:merge(Attrs, ACL),
{ok, Result}
catch
throw:{bad_acl_rule, Reason} ->
%% it's a invalid token, so ok to log