本文的目的是通過開發(fā)定制化的插件來實(shí)現(xiàn)activemq的登錄認(rèn)證。
當(dāng)然,activemq可以通過在配置文件中設(shè)置用戶、密碼對連接做簡單的鑒權(quán)認(rèn)證。
想想這個應(yīng)用場景:
1.每個mqtt client有獨(dú)自的clientId、用戶、密碼
2.隨著時間的推移,原有的mqtt client不再允許訪問broker,而新的mqtt client在持續(xù)的增加
如果成百上千的mqtt client需要連接broker,在activemq的配置文件中更新配置這些用戶、密碼,這種方式工作量大,容易出錯。
那有沒有一種方案,將需訪問的用戶、密碼保存在db中,然后通過查詢db的方式做連接認(rèn)證呢?答案是肯定的,有!
activemq提供了插件的方式讓我們靈活的做連接認(rèn)證,下面讓我們一起看看如何實(shí)現(xiàn)這個方案。
1. 創(chuàng)建一個java application,mvn文件中加入activemq的依賴包。jar包的版本與部署的activemq保持一致。
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.15.0</version>
</dependency>
2. 創(chuàng)建一個broker plunin類,這類主要是在安裝插件時,返回一個BrokerFilter。此例中返回AuthFilter,這個class請參考第3步
package com.study.mqttatuh;
import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerFilter;
import org.apache.activemq.broker.BrokerPlugin;
public class LoginAuthPlugin implements BrokerPlugin {
public Broker installPlugin(Broker broker) throws Exception {
return new AuthFilter(broker);
}
}
3. 創(chuàng)建一個broker filter。關(guān)鍵地方就在于重載了addConnection這個方法,加入了用戶密碼驗(yàn)證,如果驗(yàn)證失敗,則拋出SecurityException,這樣會導(dǎo)致mqtt client端連接失敗,從而達(dá)到認(rèn)證的目的。
package com.study.mqttatuh;
import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerFilter;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.command.ConnectionInfo;
public class AuthFilter extends BrokerFilter {
public AuthFilter(Broker next) {
super(next);
}
@Override
public void addConnection(ConnectionContext context,
ConnectionInfo info) throws Exception {
auth(info.getUserName(),info.getPassword());
super.addConnection(context, info);
}
private void auth(String userName,String password)
{
//為了演示方便寫死了要驗(yàn)證的用戶密碼,實(shí)際實(shí)施時查db驗(yàn)證
if(!"userName1".equals(userName) || !"password1".equals(password))
{
throw new SecurityException("Invalid userName or password!");
}
}
}
4.導(dǎo)出jar包。比如,此例中導(dǎo)出的jar包名為:mqttatuh-0.0.1-SNAPSHOT.jar
5.上傳jar包到activemq部署目錄的lib目錄下
[root@localhost lib]# pwd
/usr/apache-activemq-5.15.0/lib
[root@localhost lib]# ls
activemq-broker-5.15.0.jar activemq-rar.txt geronimo-jta_1.0.1B_spec-1.0.1.jar
activemq-client-5.15.0.jar activemq-spring-5.15.0.jar hawtbuf-1.11.jar
activemq-console-5.15.0.jar activemq-web-5.15.0.jar jcl-over-slf4j-1.7.25.jar
activemq-jaas-5.15.0.jar camel mqttatuh-0.0.1-SNAPSHOT.jar
activemq-kahadb-store-5.15.0.jar extra optional
activemq-openwire-legacy-5.15.0.jar geronimo-j2ee-management_1.1_spec-1.0.1.jar slf4j-api-1.7.25.jar
activemq-protobuf-1.1.jar geronimo-jms_1.1_spec-1.1.1.jar web
6.修改activemq的配置文件activemq.xml,在broker段加入自定義的插件配置(plugins段為新增的)
<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
...(省略其它配置信息)
<plugins>
<bean xmlns="http://www.springframework.org/schema/beans"
id="LoginAuthPlugin" class="com.study.mqttatuh.LoginAuthPlugin">
</bean>
</plugins>
...(省略其它配置信息)
</broker>
7.重啟activemq
至此,我們的認(rèn)證插件就安裝配置好了。mqtt client試圖建立連接時,如果提供的賬號密碼不匹配,則在AuthFilter中就會驗(yàn)證失敗報SecurityException:Invalid userName or password!
當(dāng)然此文的目的只是拋磚引玉,在AuthFilter的auth認(rèn)證方法中,可以調(diào)用其它的認(rèn)證接口服務(wù)來做登錄認(rèn)證;BrokerFilter中還有一些其它的方式,可供挖掘擴(kuò)展,比如消息攔截、日志等。