• 物联网架构成长之路(31)-EMQ基于HTTP权限验证


      看过之前的文章就知道,我之前是通过搞插件,或者通过里面的MongoDB来进行EMQ的鉴权登录和权限验证。但是前段时间发现,还是通过HTTP WebHook 方式来调用鉴权接口比较适合实际使用。还是实现设备分配一个device_id和device_key两个信息。即登录我们的业务服务器,同时登录EMQ通信服务器。免去了中间获取临时登录MQTT-Token的流程。
      下面就看这么实现基于HTTP的Auth.
      首先在EMQ的后台,管理-插件-emqx_auth_http中开启插件。(注意由于距离上次已经过去半年了,EMQ也已经升级到了3.x版本了,我这里使用EMQ 3.1.0 版本, 具体配置跟之前是差不多的。)


      下面这段代码就是主要的鉴权及权限验证代码。主要有三个WebHook函数。auth、superuser、acl。

     1 @RestController
     2 @RequestMapping(value="/iot/v1/mqtt")
     3 public class MqttAPIController {
     4 
     5     @Autowired
     6     private DeviceService deviceService;
     7     
     8     @RequestMapping(value="/auth")
     9     public ResponseRESTModel auth(HttpServletResponse response, 
    10             String clientid, String username, String password){
    11         String device_id = username;
    12         DeviceModel model = deviceService.selectOneByDeviceID(device_id);
    13         if(model == null){
    14             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    15             return ResponseRESTUtils.error(500, false);
    16         }
    17         boolean flag = SecretUtils.matchBcryptPassword(password, model.getDevice_key());
    18         if(flag == false || !model.getUuid().equals(clientid)){
    19             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    20             return ResponseRESTUtils.error(500, false);
    21         }
    22         return ResponseRESTUtils.success(true);
    23     }
    24     @RequestMapping(value="/superuser")
    25     public ResponseRESTModel superuser(HttpServletResponse response,
    26             String clientid, String username){
    27         //默认没有超级用户权限
    28         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    29         return ResponseRESTUtils.success(true);
    30     }
    31     @RequestMapping(value="/acl")
    32     public ResponseRESTModel acl(HttpServletResponse response,
    33             String clientid, String username, String access, String ipaddr, String topic){
    34         //iot/uuid/#
    35         String _acl = "iot/" + clientid + "/";
    36         if(CheckUtils.isEmpty(topic)){
    37             response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    38             return ResponseRESTUtils.error(500, false);
    39         }
    40         if(topic.startsWith(_acl)){
    41             return ResponseRESTUtils.success(true);
    42         }
    43         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
    44         return ResponseRESTUtils.error(500, false);
    45     }
    46 }

      auth:是在每次登录是都会验证一次。
      superuser:会在登录的时候调用判断是否有超级用户权限
      acl:这个会在发布或订阅数据的时候请求,判断是否允许发布或订阅,不会每次都判断,只对新Topic才进行判断,然后缓存在EMQ里面。
      WebHook采用就是标准的HTTP请求,利用HTTP response的返回状态码表示是否通过。
      详细参考官方文档: https://developer.emqx.io/docs/broker/v3/cn/plugins.html#http
      通过这种方式,比之前通过查询数据有更强的业务扩展性。比如可以判断设备是否被禁用。设备的ACL权限问题,可以更细微级控制。但是毕竟通过HTTP方式会有性能损耗,这一点为鉴权功能单独划分模块。从业务服务器独立出来单独成为一个服务。

    物联网架构成长之路系列文章目录: https://www.cnblogs.com/wunaozai/p/8067577.html

    本文地址: https://www.cnblogs.com/wunaozai/p/11147024.html
    参考资料: https://developer.emqx.io/docs/broker/v3/cn/plugins.html#http

     

  • 相关阅读:
    谈谈node(1)
    怎么调用html5的摄像头,录音,视频?
    es6-块级作用域let 和 var的区别
    输入手机号自动分隔
    How do I know which version of Javascript I'm using?
    PHP的类中的常量,静态变量的问题。
    【转】马拉松式学习与技术人员的成长性
    JavaScript Prototype in Plain Language
    Promise编程规范
    XMLHttpRequest对象解读
  • 原文地址:https://www.cnblogs.com/wunaozai/p/11147024.html
Copyright © 2020-2023  润新知