使用 HTTP 服务进行密码认证
EMQX 支持通过外部 HTTP 服务进行密码认证。客户端连接时,EMQX 将使用客户端信息构造 HTTP 请求,并根据请求返回的内容判断认证结果,从而实现复杂的认证鉴权逻辑。
前置准备:
- 熟悉 EMQX 认证基本概念
请求格式与返回结果
认证过程类似一个 HTTP API 调用,EMQX 作为请求客户端需要按照 “API” 要求的格式构造并向 HTTP 服务发起请求,而 HTTP 服务需要按照 “客户端” 的要求返回结果:
- 响应编码格式
content-type
必须是application/json
。 - 认证结果通过 body 中的
result
标示,可选allow
、deny
、ignore
。 - 超级用户通过 body 中的
is_superuser
标示,可选true
、false
。 - HTTP 响应状态码
Status Code
应当为200
或204
,返回4xx/5xx
状态码时将忽略 body 并判定结果为ignore
,继续执行认证链。
响应示例:
HTTP/1.1 200 OK
Headers: Content-Type: application/json
...
Body:
{
"result": "allow", // 可选 "allow" | "deny" | "ignore"
"is_superuser": true // 可选 true | false,该项为空时默认为 false
}
EMQX 4.x 兼容性说明
在 4.x 中,EMQX 仅用到了 HTTP API 返回的状态码,而内容则被丢弃。例如 200
表示 allow
,403
表示 deny
。因为缺乏丰富的表达能力,在 5.0 中对这一机制进行了不兼容的调整。
通过 Dashboard 配置
在 EMQX Dashboard (opens new window) 页面,点击左侧导航栏的访问控制 -> 认证,在随即打开的认证页面,单击创建,依次选择认证方式为 Password-Based
,数据源为 HTTP Server
,进入配置参数页签:
您可根据如下说明完成相关配置:
HTTP:配置请求方式与 URL。
请求方式:选择 HTTP 请求方式,可选值:
get
、post
提示
推荐使用
POST
方法。 使用GET
方法时,一些敏感信息(如纯文本密码)可能通过 HTTP 服务器日志记录暴露。此外,对于不受信任的环境,请使用 HTTPS。URL:输入 HTTP 服务的 URL 地址。
Headers(可选):HTTP 请求头配置。可以添加多个请求头。
连接配置:在此部分进行并发连接、连接超时等待时间、最大 HTTP 请求数以及请求超时时间。
- Pool size(可选):整数,指定从 EMQX 节点到外部 HTTP Server 的并发连接数;默认值:8。
- 连接超时(可选):填入连接超时等待时长,可选单位:小时、分钟、秒、毫秒。
- HTTP 管道(可选):正整数,指定无需等待响应可发出的最大 HTTP 请求数;默认值:100。
- 请求超时(可选):填入连接超时等待时长,可选单位:小时、分钟、秒、毫秒
TLS 配置:配置是否启用 TLS。
认证配置:
- Body:请求模板,对于
POST
请求,它以 JSON 形式在请求体中发送。对于GET
请求,它被编码为 URL 中的查询参数(Query String)。映射键和值可以使用 占位符。
最后点击创建完成相关配置。
通过配置文件设置
此外,您可以通过配置项完成相关配置,具体可参考:authn-http:post 与 authn-http:get。
以下为使用 POST
和 GET
请求配置的 HTTP 请求示例:
{
mechanism = password_based
backend = http
enable = true
method = post
url = "http://127.0.0.1:8080/auth?clientid=${clientid}"
body {
username = "${username}"
password = "${password}"
}
headers {
"Content-Type" = "application/json"
"X-Request-Source" = "EMQX"
}
}
注意: body 将被转换为查询字符串。
{
mechanism = password_based
backend = http
enable = true
method = get
url = "http://127.0.0.1:32333/auth"
body {
username = "${username}"
password = "${password}"
}
headers {
"X-Request-Source" = "EMQX"
}
}