Просмотр исходного кода

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

fix(authn): stop authn handling when emqx_authentication provides a result
Zaiming (Stone) Shi 3 лет назад
Родитель
Сommit
7e8381f4c7

+ 1 - 1
apps/emqx/src/emqx_authentication.erl

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

+ 18 - 5
apps/emqx/test/emqx_authentication_SUITE.erl

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

+ 1 - 0
changes/v5.0.15/fix-9785.en.md

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

+ 1 - 0
changes/v5.0.15/fix-9785.zh.md

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