refactor(auth): auth apps use counter in emqx_metrics
This commit is contained in:
parent
9435fe0bb9
commit
bd23dae523
|
@ -1,14 +1 @@
|
||||||
|
|
||||||
-define(APP, emqx_auth_http).
|
-define(APP, emqx_auth_http).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -30,22 +30,16 @@
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% Callbacks
|
%% Callbacks
|
||||||
-export([ register_metrics/0
|
-export([ check/3
|
||||||
, check/3
|
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
check(ClientInfo, AuthResult, #{auth := AuthParms = #{path := Path},
|
check(ClientInfo, AuthResult, #{auth := AuthParms = #{path := Path},
|
||||||
super := SuperParams}) ->
|
super := SuperParams}) ->
|
||||||
case authenticate(AuthParms, ClientInfo) of
|
case authenticate(AuthParms, ClientInfo) of
|
||||||
{ok, 200, <<"ignore">>} ->
|
{ok, 200, <<"ignore">>} ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore)), ok;
|
ok;
|
||||||
{ok, 200, Body} ->
|
{ok, 200, Body} ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
IsSuperuser = is_superuser(SuperParams, ClientInfo),
|
IsSuperuser = is_superuser(SuperParams, ClientInfo),
|
||||||
{stop, AuthResult#{is_superuser => IsSuperuser,
|
{stop, AuthResult#{is_superuser => IsSuperuser,
|
||||||
auth_result => success,
|
auth_result => success,
|
||||||
|
@ -54,12 +48,10 @@ check(ClientInfo, AuthResult, #{auth := AuthParms = #{path := Path},
|
||||||
{ok, Code, _Body} ->
|
{ok, Code, _Body} ->
|
||||||
?LOG(error, "Deny connection from path: ~s, response http code: ~p",
|
?LOG(error, "Deny connection from path: ~s, response http code: ~p",
|
||||||
[Path, Code]),
|
[Path, Code]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{auth_result => http_to_connack_error(Code),
|
{stop, AuthResult#{auth_result => http_to_connack_error(Code),
|
||||||
anonymous => false}};
|
anonymous => false}};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
?LOG(error, "Request auth path: ~s, error: ~p", [Path, Error]),
|
?LOG(error, "Request auth path: ~s, error: ~p", [Path, Error]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
%%FIXME later: server_unavailable is not right.
|
%%FIXME later: server_unavailable is not right.
|
||||||
{stop, AuthResult#{auth_result => server_unavailable,
|
{stop, AuthResult#{auth_result => server_unavailable,
|
||||||
anonymous => false}}
|
anonymous => false}}
|
||||||
|
|
|
@ -112,7 +112,6 @@ load_hooks() ->
|
||||||
case application:get_env(?APP, auth_req) of
|
case application:get_env(?APP, auth_req) of
|
||||||
undefined -> ok;
|
undefined -> ok;
|
||||||
{ok, AuthReq} ->
|
{ok, AuthReq} ->
|
||||||
ok = emqx_auth_http:register_metrics(),
|
|
||||||
PoolOpts = proplists:get_value(pool_opts, AuthReq),
|
PoolOpts = proplists:get_value(pool_opts, AuthReq),
|
||||||
PoolName = proplists:get_value(pool_name, AuthReq),
|
PoolName = proplists:get_value(pool_name, AuthReq),
|
||||||
{ok, _} = ehttpc_sup:start_pool(PoolName, PoolOpts),
|
{ok, _} = ehttpc_sup:start_pool(PoolName, PoolOpts),
|
||||||
|
@ -160,4 +159,3 @@ path(#{path := ""}) ->
|
||||||
"/";
|
"/";
|
||||||
path(#{path := Path}) ->
|
path(#{path := Path}) ->
|
||||||
Path.
|
Path.
|
||||||
|
|
||||||
|
|
|
@ -21,28 +21,11 @@
|
||||||
|
|
||||||
-logger_header("[JWT]").
|
-logger_header("[JWT]").
|
||||||
|
|
||||||
-export([ register_metrics/0
|
-export([ check_auth/3
|
||||||
, check_auth/3
|
|
||||||
, check_acl/5
|
, check_acl/5
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Authentication callbacks
|
%% Authentication callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -50,17 +33,16 @@ register_metrics() ->
|
||||||
check_auth(ClientInfo, AuthResult, #{from := From, checklists := Checklists}) ->
|
check_auth(ClientInfo, AuthResult, #{from := From, checklists := Checklists}) ->
|
||||||
case maps:find(From, ClientInfo) of
|
case maps:find(From, ClientInfo) of
|
||||||
error ->
|
error ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(ignore));
|
ok;
|
||||||
{ok, undefined} ->
|
{ok, undefined} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(ignore));
|
ok;
|
||||||
{ok, Token} ->
|
{ok, Token} ->
|
||||||
case emqx_auth_jwt_svr:verify(Token) of
|
case emqx_auth_jwt_svr:verify(Token) of
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(ignore));
|
ok;
|
||||||
{error, not_token} ->
|
{error, not_token} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(ignore));
|
ok;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{auth_result => Reason, anonymous => false}};
|
{stop, AuthResult#{auth_result => Reason, anonymous => false}};
|
||||||
{ok, Claims} ->
|
{ok, Claims} ->
|
||||||
{stop, maps:merge(AuthResult, verify_claims(Checklists, Claims, ClientInfo))}
|
{stop, maps:merge(AuthResult, verify_claims(Checklists, Claims, ClientInfo))}
|
||||||
|
@ -121,10 +103,8 @@ verify_acl(ClientInfo, [AclTopic | AclTopics], Topic) ->
|
||||||
verify_claims(Checklists, Claims, ClientInfo) ->
|
verify_claims(Checklists, Claims, ClientInfo) ->
|
||||||
case do_verify_claims(feedvar(Checklists, ClientInfo), Claims) of
|
case do_verify_claims(feedvar(Checklists, ClientInfo), Claims) of
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
#{auth_result => Reason, anonymous => false};
|
#{auth_result => Reason, anonymous => false};
|
||||||
ok ->
|
ok ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
#{auth_result => success, anonymous => false, jwt_claims => Claims}
|
#{auth_result => success, anonymous => false, jwt_claims => Claims}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ start(_Type, _Args) ->
|
||||||
{ok, Sup} = supervisor:start_link({local, ?MODULE}, ?MODULE, []),
|
{ok, Sup} = supervisor:start_link({local, ?MODULE}, ?MODULE, []),
|
||||||
|
|
||||||
{ok, _} = start_auth_server(jwks_svr_options()),
|
{ok, _} = start_auth_server(jwks_svr_options()),
|
||||||
ok = emqx_auth_jwt:register_metrics(),
|
|
||||||
|
|
||||||
AuthEnv = auth_env(),
|
AuthEnv = auth_env(),
|
||||||
_ = emqx:hook('client.authenticate', {emqx_auth_jwt, check_auth, [AuthEnv]}),
|
_ = emqx:hook('client.authenticate', {emqx_auth_jwt, check_auth, [AuthEnv]}),
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
|
|
||||||
-define(APP, emqx_auth_ldap).
|
-define(APP, emqx_auth_ldap).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -26,17 +26,12 @@
|
||||||
|
|
||||||
-import(emqx_auth_ldap_cli, [search/3]).
|
-import(emqx_auth_ldap_cli, [search/3]).
|
||||||
|
|
||||||
-export([ register_metrics/0
|
-export([ check/3
|
||||||
, check/3
|
|
||||||
, description/0
|
, description/0
|
||||||
, prepare_filter/4
|
, prepare_filter/4
|
||||||
, replace_vars/2
|
, replace_vars/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
check(ClientInfo = #{username := Username, password := Password}, AuthResult,
|
check(ClientInfo = #{username := Username, password := Password}, AuthResult,
|
||||||
State = #{password_attr := PasswdAttr, bind_as_user := BindAsUserRequired, pool := Pool}) ->
|
State = #{password_attr := PasswdAttr, bind_as_user := BindAsUserRequired, pool := Pool}) ->
|
||||||
CheckResult =
|
CheckResult =
|
||||||
|
@ -63,12 +58,10 @@ check(ClientInfo = #{username := Username, password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckResult of
|
case CheckResult of
|
||||||
ok ->
|
ok ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
{stop, AuthResult#{auth_result => success, anonymous => false}};
|
{stop, AuthResult#{auth_result => success, anonymous => false}};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore));
|
ok;
|
||||||
{error, ResultCode} ->
|
{error, ResultCode} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
?LOG(error, "[LDAP] Auth from ldap failed: ~p", [ResultCode]),
|
?LOG(error, "[LDAP] Auth from ldap failed: ~p", [ResultCode]),
|
||||||
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -49,7 +49,6 @@ stop(_State) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
load_auth_hook(DeviceDn) ->
|
load_auth_hook(DeviceDn) ->
|
||||||
ok = emqx_auth_ldap:register_metrics(),
|
|
||||||
Params = maps:from_list(DeviceDn),
|
Params = maps:from_list(DeviceDn),
|
||||||
emqx:hook('client.authenticate', fun emqx_auth_ldap:check/3, [Params#{pool => ?APP}]).
|
emqx:hook('client.authenticate', fun emqx_auth_ldap:check/3, [Params#{pool => ?APP}]).
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,3 @@
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-type(acl_record() :: {acl_target(), emqx_topic:topic(), action(), access(), created_at()}).
|
-type(acl_record() :: {acl_target(), emqx_topic:topic(), action(), access(), created_at()}).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
-define(TABLE, emqx_user).
|
-define(TABLE, emqx_user).
|
||||||
%% Auth callbacks
|
%% Auth callbacks
|
||||||
-export([ init/1
|
-export([ init/1
|
||||||
, register_metrics/0
|
|
||||||
, check/3
|
, check/3
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
@ -51,10 +50,6 @@ init(#{clientid_list := ClientidList, username_list := UsernameList}) ->
|
||||||
|
|
||||||
ok = ekka_mnesia:copy_table(?TABLE, disc_copies).
|
ok = ekka_mnesia:copy_table(?TABLE, disc_copies).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
hash_type() ->
|
hash_type() ->
|
||||||
application:get_env(emqx_auth_mnesia, password_hash, sha256).
|
application:get_env(emqx_auth_mnesia, password_hash, sha256).
|
||||||
|
|
||||||
|
@ -67,17 +62,14 @@ check(ClientInfo = #{ clientid := Clientid
|
||||||
end),
|
end),
|
||||||
case ets:select(?TABLE, MatchSpec) of
|
case ets:select(?TABLE, MatchSpec) of
|
||||||
[] ->
|
[] ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore)),
|
|
||||||
ok;
|
ok;
|
||||||
List ->
|
List ->
|
||||||
case match_password(NPassword, HashType, List) of
|
case match_password(NPassword, HashType, List) of
|
||||||
false ->
|
false ->
|
||||||
Info = maps:without([password], ClientInfo),
|
Info = maps:without([password], ClientInfo),
|
||||||
?LOG(info, "[Mnesia] Auth from mnesia failed: ~p", [Info]),
|
?LOG(info, "[Mnesia] Auth from mnesia failed: ~p", [Info]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
{stop, AuthResult#{anonymous => false, auth_result => password_error}};
|
||||||
_ ->
|
_ ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
{stop, AuthResult#{anonymous => false, auth_result => success}}
|
{stop, AuthResult#{anonymous => false, auth_result => success}}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -56,7 +56,6 @@ load_auth_hook() ->
|
||||||
ClientidList = application:get_env(?APP, clientid_list, []),
|
ClientidList = application:get_env(?APP, clientid_list, []),
|
||||||
UsernameList = application:get_env(?APP, username_list, []),
|
UsernameList = application:get_env(?APP, username_list, []),
|
||||||
ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}),
|
ok = emqx_auth_mnesia:init(#{clientid_list => ClientidList, username_list => UsernameList}),
|
||||||
ok = emqx_auth_mnesia:register_metrics(),
|
|
||||||
Params = #{hash_type => emqx_auth_mnesia:hash_type()},
|
Params = #{hash_type => emqx_auth_mnesia:hash_type()},
|
||||||
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]).
|
emqx:hook('client.authenticate', fun emqx_auth_mnesia:check/3, [Params]).
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
-define(APP, emqx_auth_mongo).
|
-define(APP, emqx_auth_mongo).
|
||||||
|
|
||||||
-define(DEFAULT_SELECTORS, [{<<"username">>, <<"%u">>}]).
|
-define(DEFAULT_SELECTORS, [{<<"username">>, <<"%u">>}]).
|
||||||
|
@ -14,15 +13,3 @@
|
||||||
|
|
||||||
-record(aclquery, {collection = <<"mqtt_acl">>,
|
-record(aclquery, {collection = <<"mqtt_acl">>,
|
||||||
selector = {<<"username">>, <<"%u">>}}).
|
selector = {<<"username">>, <<"%u">>}}).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("emqx/include/types.hrl").
|
-include_lib("emqx/include/types.hrl").
|
||||||
|
|
||||||
-export([ register_metrics/0
|
-export([ check/3
|
||||||
, check/3
|
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
@ -39,20 +38,15 @@
|
||||||
, available/3
|
, available/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
check(ClientInfo = #{password := Password}, AuthResult,
|
check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
Env = #{authquery := AuthQuery, superquery := SuperQuery}) ->
|
Env = #{authquery := AuthQuery, superquery := SuperQuery}) ->
|
||||||
#authquery{collection = Collection, field = Fields,
|
#authquery{collection = Collection, field = Fields,
|
||||||
hash = HashType, selector = Selector} = AuthQuery,
|
hash = HashType, selector = Selector} = AuthQuery,
|
||||||
Pool = maps:get(pool, Env, ?APP),
|
Pool = maps:get(pool, Env, ?APP),
|
||||||
case query(Pool, Collection, maps:from_list(replvars(Selector, ClientInfo))) of
|
case query(Pool, Collection, maps:from_list(replvars(Selector, ClientInfo))) of
|
||||||
undefined -> emqx_metrics:inc(?AUTH_METRICS(ignore));
|
undefined -> ok;
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?LOG(error, "[MongoDB] Can't connect to MongoDB server: ~0p", [Reason]),
|
?LOG(error, "[MongoDB] Can't connect to MongoDB server: ~0p", [Reason]),
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{auth_result => not_authorized, anonymous => false}};
|
{stop, AuthResult#{auth_result => not_authorized, anonymous => false}};
|
||||||
UserMap ->
|
UserMap ->
|
||||||
Result = case [maps:get(Field, UserMap, undefined) || Field <- Fields] of
|
Result = case [maps:get(Field, UserMap, undefined) || Field <- Fields] of
|
||||||
|
@ -64,13 +58,11 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case Result of
|
case Result of
|
||||||
ok ->
|
ok ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
{error, Error} ->
|
{error, Error} ->
|
||||||
?LOG(error, "[MongoDB] check auth fail: ~p", [Error]),
|
?LOG(error, "[MongoDB] check auth fail: ~p", [Error]),
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{auth_result => Error, anonymous => false}}
|
{stop, AuthResult#{auth_result => Error, anonymous => false}}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -68,7 +68,6 @@ safe_start() ->
|
||||||
reg_authmod(AuthQuery) ->
|
reg_authmod(AuthQuery) ->
|
||||||
case emqx_auth_mongo:available(?APP, AuthQuery) of
|
case emqx_auth_mongo:available(?APP, AuthQuery) of
|
||||||
ok ->
|
ok ->
|
||||||
emqx_auth_mongo:register_metrics(),
|
|
||||||
HookFun = fun emqx_auth_mongo:check/3,
|
HookFun = fun emqx_auth_mongo:check/3,
|
||||||
HookOptions = #{authquery => AuthQuery, superquery => undefined, pool => ?APP},
|
HookOptions = #{authquery => AuthQuery, superquery => undefined, pool => ?APP},
|
||||||
case r(super_query, application:get_env(?APP, super_query, undefined)) of
|
case r(super_query, application:get_env(?APP, super_query, undefined)) of
|
||||||
|
@ -122,4 +121,3 @@ r(auth_query, Config) ->
|
||||||
r(acl_query, Config) ->
|
r(acl_query, Config) ->
|
||||||
#aclquery{collection = list_to_binary(get_value(collection, Config, "mqtt_acl")),
|
#aclquery{collection = list_to_binary(get_value(collection, Config, "mqtt_acl")),
|
||||||
selector = get_value(selector, Config, [?DEFAULT_SELECTORS])}.
|
selector = get_value(selector, Config, [?DEFAULT_SELECTORS])}.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
|
|
||||||
-define(APP, emqx_auth_mysql).
|
-define(APP, emqx_auth_mysql).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -22,17 +22,12 @@
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
-include_lib("emqx/include/types.hrl").
|
-include_lib("emqx/include/types.hrl").
|
||||||
|
|
||||||
-export([ register_metrics/0
|
-export([ check/3
|
||||||
, check/3
|
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-define(EMPTY(Username), (Username =:= undefined orelse Username =:= <<>>)).
|
-define(EMPTY(Username), (Username =:= undefined orelse Username =:= <<>>)).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
check(ClientInfo = #{password := Password}, AuthResult,
|
check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
#{auth_query := {AuthSql, AuthParams},
|
#{auth_query := {AuthSql, AuthParams},
|
||||||
super_query := SuperQuery,
|
super_query := SuperQuery,
|
||||||
|
@ -51,15 +46,13 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckPass of
|
case CheckPass of
|
||||||
ok ->
|
ok ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore)), ok;
|
ok;
|
||||||
{error, ResultCode} ->
|
{error, ResultCode} ->
|
||||||
?LOG(error, "[MySQL] Auth from mysql failed: ~p", [ResultCode]),
|
?LOG(error, "[MySQL] Auth from mysql failed: ~p", [ResultCode]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -88,4 +81,3 @@ check_pass(Password, HashType) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
description() -> "Authentication with MySQL".
|
description() -> "Authentication with MySQL".
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,6 @@ stop(_State) ->
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
load_auth_hook(AuthQuery) ->
|
load_auth_hook(AuthQuery) ->
|
||||||
ok = emqx_auth_mysql:register_metrics(),
|
|
||||||
SuperQuery = parse_query(application:get_env(?APP, super_query, undefined)),
|
SuperQuery = parse_query(application:get_env(?APP, super_query, undefined)),
|
||||||
{ok, HashType} = application:get_env(?APP, password_hash),
|
{ok, HashType} = application:get_env(?APP, password_hash),
|
||||||
Params = #{auth_query => AuthQuery,
|
Params = #{auth_query => AuthQuery,
|
||||||
|
|
|
@ -1,13 +1 @@
|
||||||
-define(APP, emqx_auth_pgsql).
|
-define(APP, emqx_auth_pgsql).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -21,15 +21,10 @@
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
-export([ register_metrics/0
|
-export([ check/3
|
||||||
, check/3
|
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% Auth Module Callbacks
|
%% Auth Module Callbacks
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
@ -50,15 +45,13 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckPass of
|
case CheckPass of
|
||||||
ok ->
|
ok ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
{stop, AuthResult#{is_superuser => is_superuser(Pool, SuperQuery, ClientInfo),
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
emqx_metrics:inc(?AUTH_METRICS(ignore)), ok;
|
ok;
|
||||||
{error, ResultCode} ->
|
{error, ResultCode} ->
|
||||||
?LOG(error, "[Postgres] Auth from pgsql failed: ~p", [ResultCode]),
|
?LOG(error, "[Postgres] Auth from pgsql failed: ~p", [ResultCode]),
|
||||||
emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -88,4 +81,3 @@ check_pass(Password, HashType) ->
|
||||||
end.
|
end.
|
||||||
|
|
||||||
description() -> "Authentication with PostgreSQL".
|
description() -> "Authentication with PostgreSQL".
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ start(_StartType, _StartArgs) ->
|
||||||
super_query => SuperQuery,
|
super_query => SuperQuery,
|
||||||
hash_type => HashType,
|
hash_type => HashType,
|
||||||
pool => ?APP},
|
pool => ?APP},
|
||||||
ok = emqx_auth_pgsql:register_metrics(),
|
|
||||||
ok = emqx:hook('client.authenticate', fun emqx_auth_pgsql:check/3, [AuthEnv])
|
ok = emqx:hook('client.authenticate', fun emqx_auth_pgsql:check/3, [AuthEnv])
|
||||||
end),
|
end),
|
||||||
if_enabled(acl_query, fun(AclQuery) ->
|
if_enabled(acl_query, fun(AclQuery) ->
|
||||||
|
@ -59,4 +58,3 @@ if_enabled(Par, Fun) ->
|
||||||
{ok, Query} -> Fun(parse_query(Par, Query));
|
{ok, Query} -> Fun(parse_query(Par, Query));
|
||||||
undefined -> ok
|
undefined -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1 @@
|
||||||
|
|
||||||
-define(APP, emqx_auth_redis).
|
-define(APP, emqx_auth_redis).
|
||||||
|
|
||||||
-record(auth_metrics, {
|
|
||||||
success = 'client.auth.success',
|
|
||||||
failure = 'client.auth.failure',
|
|
||||||
ignore = 'client.auth.ignore'
|
|
||||||
}).
|
|
||||||
|
|
||||||
-define(METRICS(Type), tl(tuple_to_list(#Type{}))).
|
|
||||||
-define(METRICS(Type, K), #Type{}#Type.K).
|
|
||||||
|
|
||||||
-define(AUTH_METRICS, ?METRICS(auth_metrics)).
|
|
||||||
-define(AUTH_METRICS(K), ?METRICS(auth_metrics, K)).
|
|
||||||
|
|
|
@ -21,15 +21,10 @@
|
||||||
-include_lib("emqx/include/emqx.hrl").
|
-include_lib("emqx/include/emqx.hrl").
|
||||||
-include_lib("emqx/include/logger.hrl").
|
-include_lib("emqx/include/logger.hrl").
|
||||||
|
|
||||||
-export([ register_metrics/0
|
-export([ check/3
|
||||||
, check/3
|
|
||||||
, description/0
|
, description/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-spec(register_metrics() -> ok).
|
|
||||||
register_metrics() ->
|
|
||||||
lists:foreach(fun emqx_metrics:ensure/1, ?AUTH_METRICS).
|
|
||||||
|
|
||||||
check(ClientInfo = #{password := Password}, AuthResult,
|
check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
#{auth_cmd := AuthCmd,
|
#{auth_cmd := AuthCmd,
|
||||||
super_cmd := SuperCmd,
|
super_cmd := SuperCmd,
|
||||||
|
@ -52,15 +47,13 @@ check(ClientInfo = #{password := Password}, AuthResult,
|
||||||
end,
|
end,
|
||||||
case CheckPass of
|
case CheckPass of
|
||||||
ok ->
|
ok ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(success)),
|
|
||||||
IsSuperuser = is_superuser(Pool, Type, SuperCmd, ClientInfo, Timeout),
|
IsSuperuser = is_superuser(Pool, Type, SuperCmd, ClientInfo, Timeout),
|
||||||
{stop, AuthResult#{is_superuser => IsSuperuser,
|
{stop, AuthResult#{is_superuser => IsSuperuser,
|
||||||
anonymous => false,
|
anonymous => false,
|
||||||
auth_result => success}};
|
auth_result => success}};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(ignore));
|
ok;
|
||||||
{error, ResultCode} ->
|
{error, ResultCode} ->
|
||||||
ok = emqx_metrics:inc(?AUTH_METRICS(failure)),
|
|
||||||
?LOG(error, "[Redis] Auth from redis failed: ~p", [ResultCode]),
|
?LOG(error, "[Redis] Auth from redis failed: ~p", [ResultCode]),
|
||||||
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
{stop, AuthResult#{auth_result => ResultCode, anonymous => false}}
|
||||||
end.
|
end.
|
||||||
|
@ -82,4 +75,3 @@ check_pass(Password, HashType) ->
|
||||||
ok -> ok;
|
ok -> ok;
|
||||||
{error, _Reason} -> {error, not_authorized}
|
{error, _Reason} -> {error, not_authorized}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ load_auth_hook(AuthCmd) ->
|
||||||
timeout => Timeout,
|
timeout => Timeout,
|
||||||
type => Type,
|
type => Type,
|
||||||
pool => ?APP},
|
pool => ?APP},
|
||||||
ok = emqx_auth_redis:register_metrics(),
|
|
||||||
emqx:hook('client.authenticate', fun emqx_auth_redis:check/3, [Config]).
|
emqx:hook('client.authenticate', fun emqx_auth_redis:check/3, [Config]).
|
||||||
|
|
||||||
load_acl_hook(AclCmd) ->
|
load_acl_hook(AclCmd) ->
|
||||||
|
@ -66,4 +65,3 @@ if_cmd_enabled(Par, Fun) ->
|
||||||
{ok, Cmd} -> Fun(Cmd);
|
{ok, Cmd} -> Fun(Cmd);
|
||||||
undefined -> ok
|
undefined -> ok
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -299,8 +299,6 @@ handle_call({auth, RequestedClientInfo, Password},
|
||||||
case emqx_access_control:authenticate(ClientInfo1#{password => Password}) of
|
case emqx_access_control:authenticate(ClientInfo1#{password => Password}) of
|
||||||
{ok, AuthResult} ->
|
{ok, AuthResult} ->
|
||||||
emqx_logger:set_metadata_clientid(ClientId),
|
emqx_logger:set_metadata_clientid(ClientId),
|
||||||
is_anonymous(AuthResult) andalso
|
|
||||||
emqx_metrics:inc('client.auth.anonymous'),
|
|
||||||
NClientInfo = maps:merge(ClientInfo1, AuthResult),
|
NClientInfo = maps:merge(ClientInfo1, AuthResult),
|
||||||
NChannel = Channel1#channel{clientinfo = NClientInfo},
|
NChannel = Channel1#channel{clientinfo = NClientInfo},
|
||||||
case emqx_cm:open_session(true, NClientInfo, NConnInfo) of
|
case emqx_cm:open_session(true, NClientInfo, NConnInfo) of
|
||||||
|
@ -424,9 +422,6 @@ terminate(Reason, Channel) ->
|
||||||
Req = #{reason => stringfy(Reason)},
|
Req = #{reason => stringfy(Reason)},
|
||||||
try_dispatch(on_socket_closed, wrap(Req), Channel).
|
try_dispatch(on_socket_closed, wrap(Req), Channel).
|
||||||
|
|
||||||
is_anonymous(#{anonymous := true}) -> true;
|
|
||||||
is_anonymous(_AuthResult) -> false.
|
|
||||||
|
|
||||||
packet_to_message(Topic, Qos, Payload,
|
packet_to_message(Topic, Qos, Payload,
|
||||||
#channel{
|
#channel{
|
||||||
conninfo = #{proto_ver := ProtoVer},
|
conninfo = #{proto_ver := ProtoVer},
|
||||||
|
|
|
@ -412,8 +412,8 @@ emqx_collect(emqx_client_connected, Stats) ->
|
||||||
counter_metric(?C('client.connected', Stats));
|
counter_metric(?C('client.connected', Stats));
|
||||||
emqx_collect(emqx_client_authenticate, Stats) ->
|
emqx_collect(emqx_client_authenticate, Stats) ->
|
||||||
counter_metric(?C('client.authenticate', Stats));
|
counter_metric(?C('client.authenticate', Stats));
|
||||||
emqx_collect(emqx_client_auth_anonymous, Stats) ->
|
emqx_collect(emqx_client_auth_success_anonymous, Stats) ->
|
||||||
counter_metric(?C('client.auth.anonymous', Stats));
|
counter_metric(?C('client.auth.success.anonymous', Stats));
|
||||||
emqx_collect(emqx_client_check_acl, Stats) ->
|
emqx_collect(emqx_client_check_acl, Stats) ->
|
||||||
counter_metric(?C('client.check_acl', Stats));
|
counter_metric(?C('client.check_acl', Stats));
|
||||||
emqx_collect(emqx_client_subscribe, Stats) ->
|
emqx_collect(emqx_client_subscribe, Stats) ->
|
||||||
|
@ -566,7 +566,7 @@ emqx_metrics_delivery() ->
|
||||||
emqx_metrics_client() ->
|
emqx_metrics_client() ->
|
||||||
[ emqx_client_connected
|
[ emqx_client_connected
|
||||||
, emqx_client_authenticate
|
, emqx_client_authenticate
|
||||||
, emqx_client_auth_anonymous
|
, emqx_client_auth_success_anonymous
|
||||||
, emqx_client_check_acl
|
, emqx_client_check_acl
|
||||||
, emqx_client_subscribe
|
, emqx_client_subscribe
|
||||||
, emqx_client_unsubscribe
|
, emqx_client_unsubscribe
|
||||||
|
|
Loading…
Reference in New Issue