EMQ基础功能

认证

认证简介

身份认证是大多数应用的组成部分,MQTT协议支持用户名和密码认证,启用身份认证能够有效阻止非法客户端的连接
EMQ X中的认证指的是 当一个客户端连接到EMQX的时候,通过服务器的配置来控制客户端连接到服务器的权限
EMQX 的认证包括两个层面:

  • MQTT协议本身在CONNECT报文中指定用户名和密码,EMQX以插件形式支持基于Username、ClientID、Http、JWT、LDAP及各类数据库如MongoDB、MySQL、PostgreSQL、Redis等多种形式的认证
  • 在传输层上,TLS可以保证使用客户端证书的客户端到服务器的身份认证,并确保服务器向客户端验证服务器证书。也支持基于PSK的TLS/DTLS认证

认证方式

EMQX 支持使用内置数据源(文件、内置数据库)、JWT、外部主流数据库和自定义HTTP API作为身份认证的数据源。
连接数据源、进行认证逻辑通过插件实现的,每个插件对应一种认证方式,使用前需要启用相应的插件
客户端连接时 插件通过检查其 username/clientid和password是否与指定数据源的信息一致来实现对客户端的身份认证
EMQX支持的认证方式

内置数据源

  • Username认证
  • ClientID认证
    使用配置文件与EMQX内置数据库提供认证数据源,通过HTTP API进行管理,组通简单轻量

外部数据源

  • LDAP认证
  • MySQL认证
  • PostgreSQL认证
  • Redis认证
  • MongoDB认证
    外部数据库可以存储大量数据,同时方便与外部设备管理系统集成

其他

  • HTTP认证
  • JWT认证
    JWT认证可以批量签发认证信息,HTTP认证能够实现复杂的认证鉴权逻辑。
    更改插件配置后需要重启插件才能生效,部分认证鉴权插件包含ACL功能

认证结果
任何一种认证方式最终都会返回一个结果
- 认证成功: 经过比对客户端认证成功
- 认证失败: 经过比对客户端认证失败,数据源中密码与当前密码不一致
- 忽略认证:当前认证方式为查找到数据,无法显示判断结果是成功还是失败,交由认证连下一认证方式或匿名认证

匿名认证
EMQX默认配置启用了匿名认证,任何客户端都能接入EMQX,没有启用认证插件或认证插件没有显示允许/拒绝 连接请求时,EMQX将根据匿名启用情况决定是否允许客户端连接
配置匿名认证开关:

# etc/emqx.conf
## Value: true|false
allow_anonymous=true

生产环境中请禁匿名认证
注意:我们需要进入到容器内部修改该配置,然后重启EMQX服务

密码加盐规则与哈希方法

EMQX多数认证可以启用哈希方法,数据源中金保存密码密文,保证数据安全
启用哈希方法是,用户可以为每个客户端都指定一个salt(盐)并配置加盐规则,数据库中存储的密码是按照加盐规则和哈希方法处理后的密文
以MySQL认证为例:
加盐规则和哈希方法配置

# etc/plugins/emqx_auth_mysql.conf

## 不加盐,仅做hash处理
auth.mysql.passwod_hash = sha256

## salt前缀:使用sha256 加密 salt+密码 拼接的字符串
auth.mysql.passwod_hash = salt,sha256

## salt后缀:使用sha256 加密 salt+密码 拼接的字符串
auth.mysql.passwod_hash = sha256,salt

如何生成认证信息

  1. 为每个客户端分用户名、ClientId、密码记salt等信息
  2. 使用与MySQL认证相同加盐规则与哈希方法处理客户端信息得到密文
  3. 将客户端信息写入数据库,客户端的密码应当为密文信息

EMQX 身份认证流程

  1. 根据配置的认证SQL结合客户端传入的信息,查询出密码(密文)和salt(盐)等认证数据,没有查询结果时,认证将终止并返回ignore结果
  2. 根据配置的加盐规则与哈希方法得到密文,没有启用hash方法则跳过此步
  3. 将数据库中存储的密文与当前客户端计算的密文进行比对,比对成功则认证通过,否则认证失败
    请添加图片描述
    认证链
    当同时启用多个认证方式时,EMQX将按照插件开启先后顺序进行链式认证
  • 一旦认证成功,终止认证链允许客户端接入

  • 一旦认证失败,终止认证连禁止客户端接入

  • 直到最后一个认证方式仍未通过,根据
    匿名认证
    配置判定

    • 匿名认证开启时,允许客户端接入
    • 匿名认证关闭时,禁止客户端接入请添加图片描述

Username认证

Username认证使用配置文件预设客户端用户名与密码,支持通过http Api管理认证数据
Username认证不依赖外部数据源,使用上足够简单轻量。使用这种认证方式前需要开启插件,我们可以在Dashboard里找到这个插件并开启
插件: emqx_auth_username

4.3版本中emqx_auth_clientid 与 emqx_auth_usernmae 合并为 emqx_auth_mnesia

哈希方法
Username认证默认使用sha256进行密码哈希加密,可在 etc/plugins/emqx_auth_username.conf中更改

HTTP API管理认证数据

EMQX提供了对应的HTTP API用以维护内置数据源中的认证信息,我们可以在添加/查看/取消/更改认证数据
在idea中创建 rest.http 文件,把下面的 CV 到文件中测试

  1. 查看已有认证用户:GET api/v4/auth_username
@hostname = 192.168.56.132
@port = 8081
@contentType = application/json
@userName  = admin
@password = public

########## 查看已有用户认证数据 ###########
	GET http://{{hostname}}:{{port}}/api/v4/auth_username HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}
  1. 添加认证数据API定义: POST api/v4/auth_username
########添加用户数据认证##########
POST   http://{{hostname}}:{{port}}/api/v4/auth_username HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}
{
	"username":"user",
	"password":"123456"
}

code = 0表示成功
3. 更改指定用户名的密码的API定义: PUT api/v4/auth_username/${username}

######## 更改指定用户名的密码 ##########
PUT http://{{hostname}}:{{port}}/api/v4/auth_username HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}
{
	"password":"user"
}
  1. 查看指定用户信息API定义: GET api/v4/auth_username/${username}
    指定用户名,查看相关用户名、密码信息,注意此处返回的密码是使用配置文件指定哈希方式加密后的密码:
#######.查看指定用户名信息 ###########
GET http://{{hostname}}:{{port}}/api/v4/auth_username/user HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}
  1. 删除认证数据API定义: DELETE api/v4/auth_username/${username}
#######.查看指定用户名信息 ###########
DELETE http://{{hostname}}:{{port}}/api/v4/auth_username/user HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

MQTT客户端验证

使用mqtt客户端工具验证使用username连接登录的功能。从https://github.com/emqx/MQTTX 这个地址下载对应操作系统的mqtt客户端工具
请添加图片描述

Client ID认证

开启emqx_auth_clientid插件,
哈希方法
Client Id认证默认使用sha256进行密码加密,可在 etc/plugins/emqx_auth_clientid.conf中更改

HTTP API管理认证数据

  1. 添加认证数据API定义: POST api/v4/auth_clientid
#####添加clientId 和密码 #######
POST http://{{hostname}}:{{port}}/api/v4/auth_clientid HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}
{
	"clientid":"emq-client1",
	"password":"123456"
}
  1. 查看已经添加的认证数据API:GET api/v4/auth_clientid
###. 获取所有详细信息 ###
GET http://{{hostname}}:{{port}}/api/v4/auth_clientid HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

客户端验证
请添加图片描述

HTTP认证

HTTP认证使用外部自建的HTTP应用的认证数据源,根据HTTP API返回的数据判定认证结果,能够实现复杂的认证鉴权逻辑。启用该功能需要将emqx_auth_http插件开启,并且修改该插件对应的配置文件

认证原理

EMQX 在设备连接事件中使用当前客户端相关信息作为参数,向用户自定义的认证服务发起请求查询权限,通过返回HTTP响应状态码来处理认证请求

  • 认证失败:API返回4XX状态码
  • 认证成功:API返回200状态码
  • 忽略认证:API返回200状态码切消息体为ignore

操作

  1. 开启emqx_auth_http 插件
  2. 修改etc/plugins/emqx_auth_http.conf
    auth.http.auth_req = http://192.168.242.124:8991/mqtt/auth
    auth.http.auth_req.method = post
    auth.http.auth_req.params = clientid=%c,username=%u,password=%P
  3. 自建客户端
<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>
server:
  port: 8991
spring:
  application:
    name: emq-demo

@RestController
@RequestMapping("/mqtt")
public class AuthController {
    private Logger log = LoggerFactory.getLogger(AuthController.class);
    private Map<String,String> users;

    @PostConstruct
    public void init(){
        users = new HashMap<>();
        users.put("user","123456");
        users.put("emq-client2","123456");
        users.put("emq-client3","123456");
    }
    @PostMapping("/auth")
    public ResponseEntity auth(String clientid,
                               String username,
                               String password){
        log.info("emqx http认证组件开始调用任务服务完成认证服务");
        String value = users.get(username);
        if (StringUtils.isEmpty(username)) {
            return new ResponseEntity(HttpStatus.UNAUTHORIZED);
        }
        if (!value.equals(password)) {
            return new ResponseEntity(HttpStatus.UNAUTHORIZED);
        }
        return new ResponseEntity(HttpStatus.OK);

    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值