zoukankan      html  css  js  c++  java
  • 物联网架构成长之路(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

     

  • 相关阅读:
    Java如何编写自动售票机程序
    install windows service
    redis SERVER INSTALL WINDOWS SERVICE
    上传文件
    This problem will occur when running in 64 bit mode with the 32 bit Oracle client components installed.
    解决Uploadify上传控件加载导致的GET 404 Not Found问题
    OracleServiceORCL服务不见了怎么办
    Access to the temp directory is denied. Identity 'NT AUTHORITYNETWORK SERVICE' under which XmlSerializer is running does not have sufficient permiss
    MSSQL Server 2008 数据库安装失败
    数据库数据导出成XML文件
  • 原文地址:https://www.cnblogs.com/wunaozai/p/11147024.html
Copyright © 2011-2022 走看看