认证与访问控制设计

认证与访问控制设计

EMQ X 消息服务器支持可扩展的认证与访问控制,通过挂载 client.authenticate and client.check_acl 两个钩子实现。

编写鉴权钩子回调函数

挂载回调函数到 client.authenticate 钩子:

emqx:hook('client.authenticate', fun ?MODULE:on_client_authenticate/1, []).

钩子回调函数必须接受一个 Credentials 参数,并且返回一个新的 Credentials:

on_client_authenticate(Credentials = #{password := Password}) ->
    {ok, Credentials#{result => success}}.

Credentials 结构体是一个包含鉴权信息的 map:

#{
  client_id => ClientId,     %% 客户端 ID
  username  => Username,     %% 用户名
  peername  => Peername,     %% 客户端的 IP 地址和端口
  password  => Password,     %% 密码 (可选)
  result    => Result        %% 鉴权结果,success 表示认证成功,
                             %% bad_username_or_password 或者 not_authorized 表示失败.
}

编写 ACL 钩子回调函数

挂载回调函数到 client.authenticate 钩子:

emqx:hook('client.check_acl', fun ?MODULE:on_client_check_acl/4, []).

回调函数必须可接受 Credentials , AccessType , Topic , ACLResult 这几个参数, 然后返回一个新的 ACLResult:

on_client_check_acl(#{client_id := ClientId}, AccessType, Topic, ACLResult) ->
    {ok, allow}.

AccessType 可以是 publish 和 subscribe 之一。 Topic 是 MQTT topic。 ACLResult 要么是 allow ,要么是 deny 。

emqx_mod_acl_internal 模块实现了基于 etc/acl.conf 文件的 ACL 机制,etc/acl.conf 文件的默认内容:

%%%-----------------------------------------------------------------------------
%%%
%%% -type who() :: all | binary() |
%%%                {ipaddr, esockd_access:cidr()} |
%%%                {client, binary()} |
%%%                {user, binary()}.
%%%
%%% -type access() :: subscribe | publish | pubsub.
%%%
%%% -type topic() :: binary().
%%%
%%% -type rule() :: {allow, all} |
%%%                 {allow, who(), access(), list(topic())} |
%%%                 {deny, all} |
%%%                 {deny, who(), access(), list(topic())}.
%%%
%%%-----------------------------------------------------------------------------

{allow, {user, "dashboard"}, subscribe, ["$SYS/#"]}.

{allow, {ipaddr, "127.0.0.1"}, pubsub, ["$SYS/#", "#"]}.

{deny, all, subscribe, ["$SYS/#", {eq, "#"}]}.

{allow, all}.

由 emqx 提供的 Auth/ACL 插件:

Plugin Authentication
emqx_auth_username Username and Password
emqx_auth_clientid ClientID and Password
emqx_auth_ldap LDAP
emqx_auth_http HTTP API
emqx_auth_mysql MySQL
emqx_auth_pgsql PostgreSQL
emqx_auth_redis Redis
emqx_auth_mongo MongoDB
emqx_auth_jwt JWT