feat: allow using client_attrs in authentication templates

This commit is contained in:
zmstone 2024-03-21 20:36:41 +01:00
parent 8254b801ae
commit 0cf61932b6
4 changed files with 14 additions and 10 deletions

View File

@ -46,14 +46,16 @@
default_headers_no_content_type/0
]).
%% VAR_NS_CLIENT_ATTRS is not added to this list because client_attrs is to be initialized from authn result
%% VAR_NS_CLIENT_ATTRS is added here because it can be initialized before authn.
%% NOTE: authn return may add more to (or even overwrite) client_attrs.
-define(ALLOWED_VARS, [
?VAR_USERNAME,
?VAR_CLIENTID,
?VAR_PASSWORD,
?VAR_PEERHOST,
?VAR_CERT_SUBJECT,
?VAR_CERT_CN_NAME
?VAR_CERT_CN_NAME,
?VAR_NS_CLIENT_ATTRS
]).
-define(DEFAULT_RESOURCE_OPTS, #{

View File

@ -88,6 +88,7 @@
-type rule_precompile() :: {permission(), who_condition(), action_precompile(), [topic_filter()]}.
-define(IS_PERMISSION(Permission), (Permission =:= allow orelse Permission =:= deny)).
-define(ALLOWED_VARS, [?VAR_USERNAME, ?VAR_CLIENTID, ?VAR_NS_CLIENT_ATTRS]).
-spec compile(permission(), who_condition(), action_precompile(), [topic_filter()]) -> rule().
compile(Permission, Who, Action, TopicFilters) ->
@ -223,9 +224,7 @@ compile_topic(<<"eq ", Topic/binary>>) ->
compile_topic({eq, Topic}) ->
{eq, emqx_topic:words(bin(Topic))};
compile_topic(Topic) ->
Template = emqx_authz_utils:parse_str(Topic, [
?VAR_USERNAME, ?VAR_CLIENTID, ?VAR_NS_CLIENT_ATTRS
]),
Template = emqx_authz_utils:parse_str(Topic, ?ALLOWED_VARS),
case emqx_template:is_const(Template) of
true -> emqx_topic:words(bin(Topic));
false -> {pattern, Template}

View File

@ -36,7 +36,8 @@
listener => 'tcp:default',
protocol => mqtt,
cert_subject => <<"cert_subject_data">>,
cert_common_name => <<"cert_common_name_data">>
cert_common_name => <<"cert_common_name_data">>,
client_attrs => #{<<"group">> => <<"g1">>}
}).
-define(SERVER_RESPONSE_JSON(Result), ?SERVER_RESPONSE_JSON(Result, false)).
@ -655,7 +656,8 @@ samples() ->
<<"clientid">> := <<"clienta">>,
<<"peerhost">> := <<"127.0.0.1">>,
<<"cert_subject">> := <<"cert_subject_data">>,
<<"cert_common_name">> := <<"cert_common_name_data">>
<<"cert_common_name">> := <<"cert_common_name_data">>,
<<"the_group">> := <<"g1">>
} = emqx_utils_json:decode(RawBody, [return_maps]),
Req = cowboy_req:reply(
200,
@ -674,7 +676,8 @@ samples() ->
<<"password">> => ?PH_PASSWORD,
<<"peerhost">> => ?PH_PEERHOST,
<<"cert_subject">> => ?PH_CERT_SUBJECT,
<<"cert_common_name">> => ?PH_CERT_CN_NAME
<<"cert_common_name">> => ?PH_CERT_CN_NAME,
<<"the_group">> => <<"${client_attrs.group}">>
}
},
result => {ok, #{is_superuser => false, client_attrs => #{}}}

View File

@ -1578,8 +1578,8 @@ client_attrs_init {
One initial client attribute can be initialized as `client_attrs.NAME`,
where `NAME` is the name of the attribute specified in the config `extract_as`.
The initialized client attribute will be stored in the `client_attr` property with the specified name,
and can be used as a placeholder in a template.
For example, `${client_attrs.alias}` if `extract_as` is set to `alias`."""
and can be used as a placeholder in a template for authentication and authorization.
For example, use `${client_attrs.alias}` to render a HTTP POST body when `extract_as = alias`."""
}
client_attrs_init_extract_from {