展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

mqtt入门(三):emqx认证

前言

  • 该笔记学习自mqtt

起步

  • 认证方式
1. 内置数据源
username认证
clientid认证
2. 外部数据库
mysql
redis
3. 其他
jwt
http

  • 认证结果
认证成功
认证失败
忽略认证

  • 关闭匿名认证
# 进入容器内部
docker exec -it 79cc8ddd4941 /bin/sh
# 进入如下路径
cd /opt/emqx/etc
# 编辑配置文件
vi emqx.conf
# 检索配置信息,enter
/allow_anonymous
# 将配置改为false
# 保存并退出配置文件,但不退出容器
# 重启emqx
emqx restart
# 测试匿名认证是否关闭,点击连接,连接失败,说明已关闭匿名认证

  • 在数据源中对认证信息进行加密加盐
# 进入容器内的如下路径
cd /opt/emqx/etc/plugins
# 例如编辑mysql数据源
vi emqx_auth_mysql.conf
# 可以查看到连接配置,密码加密方式配置


  • 认证流程
输入用户名和密码,emqx根据不同插件连接不同的数据源,从数据源中查询用户名和密码进行认证

  • 认证链
当有多个认证方式时,先使用username进行认证,认证通过则连接成功,认证失败则不能连接,当username忽略认证时,则采用clientid进行认证,若client也是忽略,那就再下一个认证方式

username认证

  • 使用username认证,并添加认证数据
  • 启动如下插件
# 查看/opt/emqx/etc/plugins路径下的emqx_auth_username.conf
cat emqx_auth_username.conf
# 发现username认证默认配置的加密方式是sha256
# 同时可以添加用户,按如下格式添加,不过这种明文的方式不推荐使用
# 可以使用emqx提供的api来添加,添加的用户数据会存储到内置数据源中

  • 使用api添加数据
@hostname = 124.224.115.158
@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}}

########添加用户认证数据##############
POST http://{{hostname}}:{{port}}/api/v4/auth_username HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

{
    "username": "user1",
    "password": "123456"
}

###########更改指定用户名的密码#############
###http://{{hostname}}:{{port}}/api/v4/auth_username/${username}
PUT http://{{hostname}}:{{port}}/api/v4/auth_username/user HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

{
    "password": "user"
}

###########查看指定用户名信息#############
###http://{{hostname}}:{{port}}/api/v4/auth_username/${username}
GET http://{{hostname}}:{{port}}/api/v4/auth_username/user HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

###########删除指定的用户信息#############
###http://{{hostname}}:{{port}}/api/v4/auth_username/${username}
DELETE http://{{hostname}}:{{port}}/api/v4/auth_username/goudan1 HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}
  • 下载安装mqttx客户端
    https://github.com/emqx/MQTTX
  • 连接服务端,2个连接都可以使用同一账号
  • test1发送

    -test2订阅

clientid认证

  • 启动clientid的插件
  • 查看配置文件
同样已经默认设置好了密码加密方式
也可以在这里配置client + password,但不推荐
推荐使用emqx提供的api添加client和password

  • 使用api添加
####添加clientId和密码#####
POST http://{{hostname}}:{{port}}/api/v4/auth_clientid HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

{
    "clientid": "emq-client",
    "password": "123456"
}

#############获取所有详细信息########
GET http://{{hostname}}:{{port}}/api/v4/auth_clientid HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

#############更改指定 Client ID 的密码########
###http://{{hostname}}:{{port}}/api/v4/auth_clientid/${client_id}
PUT http://{{hostname}}:{{port}}/api/v4/auth_clientid/emq-client1 HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

{
    "password": "654321"
}

#############获取指定ClientId详细信息########
###http://{{hostname}}:{{port}}/api/v4/auth_clientid/${client_id}
GET http://{{hostname}}:{{port}}/api/v4/auth_clientid/emq-client1 HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

#############删除指定的client信息########
### http://{{hostname}}:{{port}}/api/v4/auth_clientid/${client_id}
DELETE http://{{hostname}}:{{port}}/api/v4/auth_clientid/emq-client2 HTTP/1.1
Content-Type: {{contentType}}
Authorization: Basic {{userName}}:{{password}}

  • 使用mqttx客户端工具测试
  • 先断开username的连接
  • 使用clientid连接
注意这里的client id需要填自己刚才通过api添加的数据
host填写服务端ip地址
username也需要填写,但不要填写正确的,否则就会就username的认证了
password必须填写clientid对应的密码


  • 收发消息测试

http认证

  • HTTP 认证使用外部自建 HTTP 应用认证数据源,根据 HTTP API 返回的数据判定认证结果,能够实现复杂的
    认证鉴权逻辑

  • 开启http认证插件

  • 认证原理

client <=> EMQ X <=> 自建http认证应用(自己的认证数据源)

客户端将用户名和密码发送到emqx服务端,服务端将数据发送到自建的http认证应用
在自建的http认证应用中认证成功,将返回结果返回给emqx服务端
服务端再决定客户端能否连接emqx
  • 查看配置文件
如下部分表示,emqx服务端在请求自建http认证应用时是使用http还是https的方式,默认是http的方式

# 表示emqx服务端在请求自建http认证应用时可以接收的请求头编码、可以接收哪些请求头,默认是所有格式
## HTTP Request Headers
##
## Example: auth.http.header.Accept-Encoding = *
##
## Value: String
## auth.http.header.Accept = */*

# 表示emqx服务端在请求自建http认证应用时,自建http认证应用的ip地址,请求方式默认是post,以及可以接收哪些参数
## Authentication request.
##
## Variables:
##  - %u: username
##  - %c: clientid
##  - %a: ipaddress
##  - %r: protocol
##  - %P: password
##  - %p: sockport of server accepted
##  - %C: common name of client TLS cert
##  - %d: subject of client TLS cert
##
## Value: URL
auth.http.auth_req = http://127.0.0.1:8991/mqtt/auth
## Value: post | get | put
auth.http.auth_req.method = post
## Value: Params
auth.http.auth_req.params = clientid=%c,username=%u,password=%P

## 重试设置
auth.http.request.retry_times = 3
auth.http.request.retry_interval = 1s
auth.http.request.retry_backoff = 2.0

  • 自建http认证应用前提
打开配置文件,配置为自己的http认证应用的ip
auth.http.auth_req = http://192.168.200.10:8991/mqtt/auth
# 将username和clientid插件先停用
  • 创建http认证应用
# 新建一个spring boot工程
# 导入依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-devtools</artifactId>
	<scope>runtime</scope>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
	<exclusions>
		<exclusion>
			<groupId>org.junit.vintage</groupId>
			<artifactId>junit-vintage-engine</artifactId>
		</exclusion>
	</exclusions>
</dependency>

# 编写配置文件
server:
  port: 8991
spring:
  application:
    name: emq-demo

# 编写控制器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
import java.util.HashMap;

@RestController
@RequestMapping("/mqtt")
public class AuthController {
    
    private static final Logger log = LoggerFactory.getLogger(AuthController.class);
    
    private HashMap<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(@RequestParam("clientid") String clientid,
                               @RequestParam("username") String username,
                               @RequestParam("password") String password){
        
        log.info("emqx http认证组件开始调用任务服务完成认证,clientid={},username={},password={}",clientid,username,password);

        String value = users.get(username);
        if(StringUtils.isEmpty(value)){
            return new ResponseEntity(HttpStatus.UNAUTHORIZED);
        }
        
        if(!value.equals(password)){
            return new ResponseEntity(HttpStatus.UNAUTHORIZED);
        }
        
        return new ResponseEntity(HttpStatus.OK);
    }
    
}

  • 使用MQTTX连接工具测试连接
posted @ 2022-03-19 19:55  DogLeftover  阅读(1281)  评论(0编辑  收藏  举报