fix: exhook client.authorize never be execauted

see: https://github.com/emqx/emqx/issues/8779
This commit is contained in:
JianBo He 2022-08-23 15:26:05 +08:00 committed by firest
parent 47648b3874
commit 168f44e45b
3 changed files with 28 additions and 22 deletions

View File

@ -17,6 +17,7 @@
-module(emqx_access_control). -module(emqx_access_control).
-include("emqx.hrl"). -include("emqx.hrl").
-include("logger.hrl").
-export([ -export([
authenticate/1, authenticate/1,
@ -70,9 +71,26 @@ check_authorization_cache(ClientInfo, PubSub, Topic) ->
do_authorize(ClientInfo, PubSub, Topic) -> do_authorize(ClientInfo, PubSub, Topic) ->
NoMatch = emqx:get_config([authorization, no_match], allow), NoMatch = emqx:get_config([authorization, no_match], allow),
case run_hooks('client.authorize', [ClientInfo, PubSub, Topic], NoMatch) of Default = #{result => NoMatch, from => default},
allow -> allow; case run_hooks('client.authorize', [ClientInfo, PubSub, Topic], Default) of
_Other -> deny AuthzResult = #{result := Result} when Result == allow; Result == deny ->
From = maps:get(from, AuthzResult, unknown),
emqx:run_hook(
'client.check_authz_complete',
[ClientInfo, PubSub, Topic, Result, From]
),
Result;
Other ->
?SLOG(error, #{
msg => "unknown_authorization_return_format",
expected_example => "#{result => allow, from => default}",
got => Other
}),
emqx:run_hook(
'client.check_authz_complete',
[ClientInfo, PubSub, Topic, deny, unknown_return_format]
),
deny
end. end.
-compile({inline, [run_hooks/3]}). -compile({inline, [run_hooks/3]}).

View File

@ -319,7 +319,7 @@ authorize(
is_superuser => true is_superuser => true
}), }),
emqx_metrics:inc(?METRIC_SUPERUSER), emqx_metrics:inc(?METRIC_SUPERUSER),
{stop, allow}; {stop, #{result => allow, from => superuser}};
false -> false ->
authorize_non_superuser(Client, PubSub, Topic, DefaultResult, Sources) authorize_non_superuser(Client, PubSub, Topic, DefaultResult, Sources)
end. end.
@ -331,15 +331,11 @@ authorize_non_superuser(
} = Client, } = Client,
PubSub, PubSub,
Topic, Topic,
DefaultResult, _DefaultResult,
Sources Sources
) -> ) ->
case do_authorize(Client, PubSub, Topic, sources_with_defaults(Sources)) of case do_authorize(Client, PubSub, Topic, sources_with_defaults(Sources)) of
{{matched, allow}, AuthzSource} -> {{matched, allow}, AuthzSource} ->
emqx:run_hook(
'client.check_authz_complete',
[Client, PubSub, Topic, allow, AuthzSource]
),
log_allowed(#{ log_allowed(#{
username => Username, username => Username,
ipaddr => IpAddress, ipaddr => IpAddress,
@ -348,12 +344,8 @@ authorize_non_superuser(
}), }),
emqx_metrics_worker:inc(authz_metrics, AuthzSource, allow), emqx_metrics_worker:inc(authz_metrics, AuthzSource, allow),
emqx_metrics:inc(?METRIC_ALLOW), emqx_metrics:inc(?METRIC_ALLOW),
{stop, allow}; {stop, #{result => allow, from => AuthzSource}};
{{matched, deny}, AuthzSource} -> {{matched, deny}, AuthzSource} ->
emqx:run_hook(
'client.check_authz_complete',
[Client, PubSub, Topic, deny, AuthzSource]
),
?SLOG(warning, #{ ?SLOG(warning, #{
msg => "authorization_permission_denied", msg => "authorization_permission_denied",
username => Username, username => Username,
@ -363,12 +355,8 @@ authorize_non_superuser(
}), }),
emqx_metrics_worker:inc(authz_metrics, AuthzSource, deny), emqx_metrics_worker:inc(authz_metrics, AuthzSource, deny),
emqx_metrics:inc(?METRIC_DENY), emqx_metrics:inc(?METRIC_DENY),
{stop, deny}; {stop, #{result => deny, from => AuthzSource}};
nomatch -> nomatch ->
emqx:run_hook(
'client.check_authz_complete',
[Client, PubSub, Topic, DefaultResult, default]
),
?SLOG(info, #{ ?SLOG(info, #{
msg => "authorization_failed_nomatch", msg => "authorization_failed_nomatch",
username => Username, username => Username,
@ -377,7 +365,7 @@ authorize_non_superuser(
reason => "no-match rule" reason => "no-match rule"
}), }),
emqx_metrics:inc(?METRIC_NOMATCH), emqx_metrics:inc(?METRIC_NOMATCH),
{stop, DefaultResult} ignore
end. end.
log_allowed(Meta) -> log_allowed(Meta) ->

View File

@ -133,7 +133,7 @@ on_client_authenticate(ClientInfo, AuthResult) ->
end. end.
on_client_authorize(ClientInfo, PubSub, Topic, Result) -> on_client_authorize(ClientInfo, PubSub, Topic, Result) ->
Bool = Result == allow, Bool = maps:get(result, Result, deny) == allow,
Type = Type =
case PubSub of case PubSub of
publish -> 'PUBLISH'; publish -> 'PUBLISH';
@ -158,7 +158,7 @@ on_client_authorize(ClientInfo, PubSub, Topic, Result) ->
true -> allow; true -> allow;
_ -> deny _ -> deny
end, end,
{StopOrOk, NResult}; {StopOrOk, #{result => NResult, from => exhook}};
_ -> _ ->
{ok, Result} {ok, Result}
end. end.