Merge pull request #9785 from savonarola/fix-authn-handling

fix(authn): stop authn handling when emqx_authentication provides a result
This commit is contained in:
Zaiming (Stone) Shi 2023-01-18 13:24:22 +01:00 committed by GitHub
commit 7e8381f4c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 6 deletions

View File

@ -661,7 +661,7 @@ do_authenticate(
_ -> _ ->
ok ok
end, end,
{ok, Result} {stop, Result}
catch catch
Class:Reason:Stacktrace -> Class:Reason:Stacktrace ->
?TRACE_AUTHN(warning, "authenticator_error", #{ ?TRACE_AUTHN(warning, "authenticator_error", #{

View File

@ -106,6 +106,10 @@ authenticate(#{username := <<"good">>}, _State) ->
{ok, #{is_superuser => true}}; {ok, #{is_superuser => true}};
authenticate(#{username := <<"ignore">>}, _State) -> authenticate(#{username := <<"ignore">>}, _State) ->
ignore; ignore;
authenticate(#{username := <<"emqx_authn_ignore_for_hook_good">>}, _State) ->
ignore;
authenticate(#{username := <<"emqx_authn_ignore_for_hook_bad">>}, _State) ->
ignore;
authenticate(#{username := _}, _State) -> authenticate(#{username := _}, _State) ->
{error, bad_username_or_password}. {error, bad_username_or_password}.
@ -117,6 +121,10 @@ hook_authenticate(#{username := <<"hook_user_finally_good">>}, _AuthResult) ->
{stop, {ok, ?NOT_SUPERUSER}}; {stop, {ok, ?NOT_SUPERUSER}};
hook_authenticate(#{username := <<"hook_user_finally_bad">>}, _AuthResult) -> hook_authenticate(#{username := <<"hook_user_finally_bad">>}, _AuthResult) ->
{stop, {error, invalid_username}}; {stop, {error, invalid_username}};
hook_authenticate(#{username := <<"emqx_authn_ignore_for_hook_good">>}, _AuthResult) ->
{ok, {ok, ?NOT_SUPERUSER}};
hook_authenticate(#{username := <<"emqx_authn_ignore_for_hook_bad">>}, _AuthResult) ->
{stop, {error, invalid_username}};
hook_authenticate(_ClientId, AuthResult) -> hook_authenticate(_ClientId, AuthResult) ->
{ok, AuthResult}. {ok, AuthResult}.
@ -595,12 +603,17 @@ t_combine_authn_and_callback(Config) when is_list(Config) ->
?assertAuthFailureForUser(bad), ?assertAuthFailureForUser(bad),
?assertAuthFailureForUser(ignore), ?assertAuthFailureForUser(ignore),
%% lower-priority hook can overrride auth result, %% lower-priority hook can overrride emqx_authentication result
%% because emqx_authentication permits/denies with {ok, ...} %% for ignored users
?assertAuthSuccessForUser(hook_user_good), ?assertAuthSuccessForUser(emqx_authn_ignore_for_hook_good),
?assertAuthFailureForUser(hook_user_bad), ?assertAuthFailureForUser(emqx_authn_ignore_for_hook_bad),
?assertAuthSuccessForUser(hook_user_finally_good),
%% lower-priority hook cannot overrride
%% successful/unsuccessful emqx_authentication result
?assertAuthFailureForUser(hook_user_finally_good),
?assertAuthFailureForUser(hook_user_finally_bad), ?assertAuthFailureForUser(hook_user_finally_bad),
?assertAuthFailureForUser(hook_user_good),
?assertAuthFailureForUser(hook_user_bad),
ok = unhook(); ok = unhook();
t_combine_authn_and_callback({'end', Config}) -> t_combine_authn_and_callback({'end', Config}) ->

View File

@ -0,0 +1 @@
Stop authentication hook chain if `emqx_authentication` provides a definitive result.

View File

@ -0,0 +1 @@
如果 `emqx_authentication` 提供了确定的结果,则停止认证钩子链。