看過之前的文章就知道,我之前是通過搞插件,或者通過里面的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