Merge pull request #8426 from zmstone/0705-add-quick-deny-for-anonymous
feat: add a quick deny option to allow_anonymous config
This commit is contained in:
commit
3db6fd85bb
|
@ -807,7 +807,7 @@ end}.
|
|||
%% @doc Allow anonymous authentication.
|
||||
{mapping, "allow_anonymous", "emqx.allow_anonymous", [
|
||||
{default, false},
|
||||
{datatype, {enum, [true, false]}}
|
||||
{datatype, {enum, [true, false, false_quick_deny]}}
|
||||
]}.
|
||||
|
||||
%% @doc ACL nomatch.
|
||||
|
@ -962,7 +962,7 @@ end}.
|
|||
]}.
|
||||
|
||||
{mapping, "zone.$name.allow_anonymous", "emqx.zones", [
|
||||
{datatype, {enum, [true, false]}}
|
||||
{datatype, {enum, [true, false, false_quick_deny]}}
|
||||
]}.
|
||||
|
||||
{mapping, "zone.$name.acl_nomatch", "emqx.zones", [
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
%% the emqx `release' version, which in turn is comprised of several
|
||||
%% apps, one of which is this. See `emqx_release.hrl' for more
|
||||
%% info.
|
||||
{vsn, "4.3.17"}, % strict semver, bump manually!
|
||||
{vsn, "4.3.18"}, % strict semver, bump manually!
|
||||
{modules, []},
|
||||
{registered, []},
|
||||
{applications, [ kernel
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
%% -*- mode: erlang -*-
|
||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||
{VSN,
|
||||
[{"4.3.16",
|
||||
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||
[{"4.3.17",[{load_module,emqx_access_control,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.16",
|
||||
[{load_module,emqx_access_control,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_metrics,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||
|
@ -650,8 +652,10 @@
|
|||
{load_module,emqx_message,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_limiter,brutal_purge,soft_purge,[]}]},
|
||||
{<<".*">>,[]}],
|
||||
[{"4.3.16",
|
||||
[{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||
[{"4.3.17",[{load_module,emqx_access_control,brutal_purge,soft_purge,[]}]},
|
||||
{"4.3.16",
|
||||
[{load_module,emqx_access_control,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_plugins,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_metrics,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_app,brutal_purge,soft_purge,[]},
|
||||
{load_module,emqx_access_rule,brutal_purge,soft_purge,[]},
|
||||
|
|
|
@ -33,15 +33,13 @@
|
|||
|
||||
-spec(authenticate(emqx_types:clientinfo()) -> {ok, result()} | {error, term()}).
|
||||
authenticate(ClientInfo = #{zone := Zone}) ->
|
||||
AuthResult = default_auth_result(Zone),
|
||||
case
|
||||
begin ok = emqx_metrics:inc('client.authenticate'),
|
||||
emqx_zone:get_env(Zone, bypass_auth_plugins, false)
|
||||
end
|
||||
of
|
||||
true ->
|
||||
ok = emqx_metrics:inc('client.authenticate'),
|
||||
Username = maps:get(username, ClientInfo, undefined),
|
||||
{MaybeStop, AuthResult} = default_auth_result(Username, Zone),
|
||||
case MaybeStop of
|
||||
stop ->
|
||||
return_auth_result(AuthResult);
|
||||
false ->
|
||||
continue ->
|
||||
return_auth_result(emqx_hooks:run_fold('client.authenticate', [ClientInfo], AuthResult))
|
||||
end.
|
||||
|
||||
|
@ -91,10 +89,29 @@ inc_acl_metrics(cache_hit) ->
|
|||
emqx_metrics:inc('client.acl.cache_hit').
|
||||
|
||||
%% Auth
|
||||
default_auth_result(Zone) ->
|
||||
case emqx_zone:get_env(Zone, allow_anonymous, false) of
|
||||
true -> #{auth_result => success, anonymous => true};
|
||||
false -> #{auth_result => not_authorized, anonymous => false}
|
||||
default_auth_result(Username, Zone) ->
|
||||
IsAnonymous = (Username =:= undefined orelse Username =:= <<>>),
|
||||
AllowAnonymous = emqx_zone:get_env(Zone, allow_anonymous, false),
|
||||
Bypass = emqx_zone:get_env(Zone, bypass_auth_plugins, false),
|
||||
%% the `anonymous` field in auth result does not mean the client is
|
||||
%% connected without username, but if the auth result is based on
|
||||
%% allowing anonymous access.
|
||||
IsResultBasedOnAllowAnonymous =
|
||||
case AllowAnonymous of
|
||||
true -> true;
|
||||
_ -> false
|
||||
end,
|
||||
Result = case AllowAnonymous of
|
||||
true -> #{auth_result => success, anonymous => IsResultBasedOnAllowAnonymous};
|
||||
_ -> #{auth_result => not_authorized, anonymous => IsResultBasedOnAllowAnonymous}
|
||||
end,
|
||||
case {IsAnonymous, AllowAnonymous} of
|
||||
{true, false_quick_deny} ->
|
||||
{stop, Result};
|
||||
_ when Bypass ->
|
||||
{stop, Result};
|
||||
_ ->
|
||||
{continue, Result}
|
||||
end.
|
||||
|
||||
-compile({inline, [return_auth_result/1]}).
|
||||
|
|
|
@ -38,6 +38,12 @@ t_authenticate(_) ->
|
|||
emqx_zone:set_env(zone, allow_anonymous, true),
|
||||
?assertMatch({ok, _}, emqx_access_control:authenticate(clientinfo())).
|
||||
|
||||
t_authenticate_fast_fail(_) ->
|
||||
emqx_zone:set_env(zone, allow_anonymous, false_quick_deny),
|
||||
?assertMatch({error, _}, emqx_access_control:authenticate(clientinfo())),
|
||||
emqx_zone:set_env(zone, allow_anonymous, true),
|
||||
?assertMatch({ok, _}, emqx_access_control:authenticate(clientinfo())).
|
||||
|
||||
t_check_acl(_) ->
|
||||
emqx_zone:set_env(zone, acl_nomatch, deny),
|
||||
application:set_env(emqx, enable_acl_cache, false),
|
||||
|
|
Loading…
Reference in New Issue