物聯網架構成長之路(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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM