`

6.3 创建自定义安全插件

 
阅读更多

博客已搬家, 更好的阅读体验,请移步: http://www.jack-yin.com/english/translation/activemq-in-action/1089.html

 

6.3 Building a custom security plug-in

6.3 创建自定义安全插件

 

So far this chapter has focused on the built-in security features in ActiveMQ. Though

these features should provide enough functionality for the majority of users, an even

more powerful feature is available. As stated previously, the ActiveMQ plug-in API is

extremely flexible and the possibilities are endless. The flexibility in this functionality

comes from the BrokerFilter class. This class provides the ability to intercept many

of the available broker-level operations. Broker operations include such items as adding

consumers and producers to the broker, committing transactions in the broker,

and adding and removing connections to the broker, to name a few. Custom functionality

can be added by extending the BrokerFilter class and overriding a method for a

given operation.

 

到目前为止,本章讨论的内容都是ActiveMQ自带的安全功能.尽管这些自带的功能已足够绝大多数用户使用,

但是ActiveMQ还提供了一种更加强大的功能.前面已经提到,ActiveMQ的插件API具有强大的灵活性,其支持的

功能是无穷无尽的.ActiveMQ的灵活性来自于BrokerFilter类的功能.该类提供了一种拦截大多数可用代理的

各种操作功能.代理的操作包扩:为代理增加消息生产者和消费者,提交代理的事务,增加/移除到代理的连接,

等等.可以通过扩展BrokerFilter类并且为特定的操作覆盖相关的方法来实现自定义功能.

 

Though the ActiveMQ plug-in API isn’t concerned solely with security, implementing

a class whose main purpose is to handle a custom security feature is achievable. So

if you have security requirements that can’t be met using the previous security features,

you may want to consider developing a custom solution for your needs. Depending

on your needs, two choices are available:

 

尽管ActiveMQ的插件API不仅仅关注安全机制,但是实现一个主要用于处理自定义安全的类是可行的.

因此,如果你有安全方面的需求且该需求不能使用前面介绍的ActiveMQ自带的安全机制来解决,你可以

考虑使用自定义功能来实现自己的需求.基于你的需求,有两种方式可供选择:

 

 Implement a JAAS login module—There’s a good chance that you’re already using

JAAS in your Java applications. In this case, it’s only natural that you’ll try to

reuse all that work for securing the ActiveMQ broker, too. Since JAAS isn’t the

main topic of this book, we won’t dive any deeper into this topic than we

already have.

 

方式一:实现一个JAAS登陆模块 -- 如果你已经在你的应用程序中使用JAAS的话,这是一个不错的选择.

这种情况下,你可以很自然的想到在ActiveMQ代理中重用已实现的JASS登陆模块.因为JAAS不是本书讨论的

主题,我们不打算更深入的介绍JAAS.

 

 Implement a custom plug-in for handling security—ActiveMQ provides a flexible

generic plug-in mechanism. You can create your own custom plug-ins for just

about anything, including custom security plug-ins. So if you have requirements

that can’t be met by implementing a JAAS module, writing a custom plug-in is

the way to go.

 

方式二:实现自定义的插件为处理ActiveMQ安全提供了一个灵活的机制.你可以创建自定义的插件来处理

任何事情,当包含自定义的安全插件.因此假如你有一个不能通过实现JAAS登陆模块来完成需求,你可以写

一个自定义插件来完成.

 

In this section we’ll describe how to write a simple security plug-in that authorizes broker

connections only from a certain set of IP addresses. The concept isn’t complex but

is good enough to give you a taste of the BrokerFilter with an angle toward security.

 

本节中我们将介绍如何通过写一个简单的安全插件来限制只有IP地址属于指定IP地址集合的客户端才能连接

到代理.这个插件涉及到的概念不是很复杂,但是作为在安全角度尝试BrokerFilter的应用来说已经相当好了.

 

6.3.1 Implementing the plug-in

6.3.1 实现插件

 

In order to limit connectivity to the broker based on IP address, we’ll create a class

named IPAuthenticationBroker to override the BrokerFilter.addConnection()

method. The implementation of this method will perform a simple check of the IP

address using a regular expression to determine the ability to connect. The following

listing shows the implementation of the IPAuthenticationBroker class.

 

为了根据客户端的IP地址来限制到代理的连接,我们创建一个名称为IPAuthenticationBroker的方法以

覆盖BrokerFilter.addConnection()方法.该方法中将使用正则表达式简单的检查客户端的IP地址以便

决定客户端能否连接到代理.下面是IPAuthenticationBroker方法的代码清单:

 

Listing 6.4 IPAuthenticationBroker class—custom broker implementation

清单6.4 IPAuthenticationBroker类 -- 实现自定义代理

 

public class IPAuthenticationBroker extends BrokerFilter 

{

  List<String> allowedIPAddresses;

  Pattern pattern = Pattern.compile("^/([0-9\\.]*):(.*)");

 

  public IPAuthenticationBroker(Broker next, List<String> allowedIPAddresses) 

  {

    super(next);

    this.allowedIPAddresses = allowedIPAddresses;

  }

  

  public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception 

  {

    String remoteAddress = context.getConnection().getRemoteAddress();

    Matcher matcher = pattern.matcher(remoteAddress);

    if (matcher.matches()) 

    {

      String ip = matcher.group(1);

      if (!allowedIPAddresses.contains(ip)) 

      {

        throw new SecurityException("Connecting from IP address " + ip + " is not allowed" );

      }

    } 

    else 

    {

      throw new SecurityException("Invalid remote address " + remoteAddress);

    }

    super.addConnection(context, info);

  }

}

 

The BrokerFilter class defines methods that intercept broker operations such as adding

a connection, removing a subscriber, and so forth. In the IPAuthenticationBroker

class, the addConnection() method is overridden to create some logic that checks

whether the address of a connecting client falls within a list of IP addresses that are

allowed to connect. If that IP address is allowed to connect, the call is delegated to the

BrokerFilter. addConnection() method. If that IP address isn’t allowed to connect,

an exception is thrown.

 

BrokerFilter类定义了一些方法,这些方法可以拦截代理的一些操作,比如:增加一个连接,移除一个消息

订阅者,等等.在IPAuthenticationBroker类中,addConnection()方法被覆盖了以便创建一些检查客户端

IP地址是否在允许IP地址列表之内的逻辑.如果当前的IP地址可以连接到代理,对该方法的调用将转移给

BrokerFilter类的addConnection() 方法来处理.如果当前的IP地址不允许连接,则会抛出一个异常.

 

One additional item of note in the IPAuthenticationBroker class is that its constructor

calls the BrokerFilter’s constructor. This call serves to set up the chain of

interceptors so that the proper cascading will take place through the chain. Don’t forget

to do this if you create your own BrokerFilter implementation.

 

关于IPAuthenticationBroker类需要额外注意的是,该类的构造函数调用了BrokerFilter类的构造函数.

这样调用设置了拦截链,以便建立正确的拦截链级联.在创建你自己的BrokerFilter实现时,不要忘记

在构造函数中做这种处理.

 

After the actual plug-in logic has been implemented, the plug-in must be configured

and installed. For this purpose, an implementation of the BrokerPlugin will be

created. The BrokerPlugin is used to expose the configuration of a plug-in and also

to install the plug-in into the ActiveMQ broker. In order to configure and install the

IPAuthenticationBroker, the IPAuthenticationPlugin class is created as shown in

the following listing.

 

当实现了插件的真正逻辑后,还必须要配置和安装插件.为此,需要实现BrokerPlugin,该类用于将一个

插件暴露给ActiveMQ代理,以便代理能够安装它.为了配置和安装插件,创建IPAuthenticationPlugin

类,其代码如下所示:

 

Listing 6.5 IPAuthenticationPlugin class—custom plug-in implementation

清单6.5 IPAuthenticationPlugin类 -- 自实现定义插件

 

public class IPAuthenticationPlugin implements BrokerPlugin 

{

  List<String> allowedIPAddresses;

  public Broker installPlugin(Broker broker) throws Exception 

  {

    return new IPAuthenticationBroker(broker, allowedIPAddresses);

  }

  

  public List<String> getAllowedIPAddresses() 

  {

    return allowedIPAddresses;

  }

  

  public void setAllowedIPAddresses(List<String> allowedIPAddresses) 

  {

    this.allowedIPAddresses = allowedIPAddresses;

  }

}

 

 

The IPAuthenticationBroker.installPlugin() method is used to instantiate the

plug-in and return a new intercepted broker for the next plug-in in the chain. Note

that the IPAuthenticationPlugin class also contains getter and setter methods used

to configure the IPAuthenticationBroker. These setter and getter methods are then

available via a Spring beans–style XML configuration in the ActiveMQ XML configuration

file (as you’ll see in a moment).

 

IPAuthenticationBroker的installPlugin()方法用来初始化插件然后返回一个被拦截的代理,

该代理用于拦截链中的下一个插件.需要注意的是,IPAuthenticationPlugin还包含getter和

setter方法用于配置IPAuthenticationBroker类--setter和getter方法可用于ActiveMQ的Spring 

beans风格的XML配置文件(稍后将看到).

 

6.3.2 Configuring the plug-in

6.3.2 配置插件

 

Now that we’ve implemented the plug-in, let’s see how we can configure it using

the ActiveMQ XML configuration file. The following listing shows how the

IPAuthenticationPlugin class is used in configuration.

实现了自定义插件后,让我们再看看如何使用该自定义插件配置ActiveMQ的XML配置文件.

下面的配置代码清单中显示了如何在配置文件中配置IPAuthenticationPlugin.

 

Listing 6.6 Configuring the custom plug-in

<broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.base}/data">

  <plugins>

    <bean xmlns="http://www.springframework.org/schema/beans" id="ipAuthenticationPlugin" class="org.apache.activemq.book.ch6.IPAuthenticationPlugin">

      <property name="allowedIPAddresses">

        <list>

          <value>127.0.0.1</value>

        </list>

      </property>

    </bean>

  </plugins>

 

  <transportConnectors>

    <transportConnector name="openwire" uri="tcp://localhost:61616" />

  </transportConnectors>

</broker>

 

The <broker> element provides the plugins element for declaring plug-ins. Using

the IPAuthenticationPlugin, only those clients connecting from the IP address

127.0.0.1 (the localhost) can actually connect to the broker.

 

<broker>元素的plugins子元素用于定义插件.使用IPAuthenticationPlugin插件后,连接到

代理的客户端中只有IP地址为127.0.0.1(localhost)的客户端才能连到代理.

 

6.3.3 Testing the plug-in

6.3.3 测试插件

 

All that needs to be done now is to test the plug-in. Here’s the command to copy the

examples JAR file into place (because it contains the plug-in) and the command to

start up ActiveMQ using the IPAuthenticationPlugin and the IPAuthentication-

Broker:

现在要做的就是测试常见了.下面的命令首先,复制示例中的jar包(因为该jar包中含有插件类)到

合适的位置,然后启动使用了IPAuthenticationPlugin和IPAuthentication的代理:

 

$ cp target/activemq-in-action-examples.jar ${ACTIVEMQ_HOME}/lib/

 

$ {ACTIVEMQ_HOME}/bin/activemq console xbean:src/main/resources/org/apache/activemq/book/ch6/activemq-custom.xml

 

(译注:window中的命令 %ACTIVEMQ_HOME%/bin/activemq xbean:src/main/resources/org/apache/activemq/book/ch6/activemq-custom.xml)

(译注:使用ActiveMQ5.8测试,原始源码中的配置文件貌似有问题,已改成下面这样:

activemq-custom.xml

<beans 

  xmlns="http://www.springframework.org/schema/beans"

  xmlns:amq="http://activemq.apache.org/schema/core"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

  http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">

 

 

<!-- Allows us to use system properties as variables in this configuration file -->

<bean

class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />

 

<broker xmlns="http://activemq.apache.org/schema/core"

brokerName="localhost" dataDirectory="${activemq.base}/data" >

 

<!-- The transport connectors ActiveMQ will listen to -->

<transportConnectors>

<transportConnector name="openwire"

uri="tcp://localhost:61616" />

</transportConnectors>

    

    <plugins>

      <bean xmlns="http://www.springframework.org/schema/beans" id="ipAuthenticationPlugin" class="org.apache.activemq.book.ch6.IPAuthenticationPlugin">

        <property name="allowedIPAddresses">

          <list>

            <value>127.0.0.1</value>

          </list>

        </property>

      </bean>

    </plugins>

  

</broker>

 

 

 

</beans>

)

 

...

Loading message broker from: xbean:src/main/resources/org/apache/activemq/book/ch6/activemq-custom.xml

...

23:22:46,982 | INFO | PListStore:/Users/bsnyder/amq/apache-activemq-5.4.1/data/localhost/tmp_storage started

23:22:47,156 | INFO | JMX consoles can connect to service: jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi

23:22:47,159 | INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[/Users/bsnyder/amq/apache-activemq-5.4.1/data/localhost/KahaDB]

23:22:48,033 | INFO | KahaDB is version 2

23:22:48,083 | INFO | ActiveMQ 5.4.1 JMS Message Broker (localhost) isstarting

23:22:48,084 | INFO | For help or more information please see:http://activemq.apache.org/

23:22:48,234 | INFO | Scheduler using directory:/Users/bsnyder/amq/apache-activemq-5.4.1/data/localhost/scheduler

23:22:48,275 | INFO | JobSchedulerStore:/Users/bsnyder/amq/apache-activemq-5.4.1/data/localhost/scheduler started

23:22:48,317 | INFO | Listening for connections at: tcp://localhost:61616

23:22:48,317 | INFO | Connector openwire Started

23:22:48,319 | INFO | ActiveMQ JMS Message Broker

(localhost, ID:mongoose.local-49947-1289974968106-0:0) started

...

 

Now run the client to connect to ActiveMQ from the localhost and everything should

be working fine. See the following output:

接着,使用下面的命令,在localhost上运行客户端以连接到ActiveMQ,程序运行应该一切正常.命令后面面是程序输出信息:

 

$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch3.portfolio.Publisher -Dexec.args="CSCO ORCL"

...

Sending: {price=0.7137712112409276, stock=ORCL, offer=0.7144849824521684,up=true} on destination: topic://STOCKS.ORCL

Sending: {price=0.7127548328743109, stock=ORCL, offer=0.7134675877071851,up=false} on destination: topic://STOCKS.ORCL

Sending: {price=0.710497871629952, stock=ORCL, offer=0.711208369501582,up=false} on destination: topic://STOCKS.ORCL

Sending: {price=0.7167766362460622, stock=ORCL, offer=0.7174934128823083,up=true} on destination: topic://STOCKS.ORCL

Sending: {price=54.586310464064766, stock=CSCO, offer=54.64089677452883,up=false} on destination: topic://STOCKS.CSCO

Sending: {price=54.45678231194236, stock=CSCO, offer=54.5112390942543,up=false} on destination: topic://STOCKS.CSCO

Sending: {price=0.7134830573922482, stock=ORCL, offer=0.7141965404496403,up=false} on destination: topic://STOCKS.ORCL

Sending: {price=0.7125898470778729, stock=ORCL, offer=0.7133024369249507,up=false} on destination: topic://STOCKS.ORCL

Sending: {price=0.7106363691848542, stock=ORCL, offer=0.711347005554039,up=false} on destination: topic://STOCKS.ORCL

Sending: {price=54.99339386523512, stock=CSCO, offer=55.04838725910035,up=true} on destination: topic://STOCKS.CSCO

Published '10' of '10' price messages

...

 

If a connection attempt is made from any host other than the localhost, you can

expect to see the following output including the exception:

如果有非localhost的客户端尝试连接到代理,你将看到下面的输出中显示的异常信息:

 

$ mvn exec:java -Dexec.mainClass=org.apache.activemq.book.ch3.portfolio.Publisher -Dexec.args="CSCO ORCL"

...

Exception in thread "main"

javax.jms.JMSException: Connecting from IP address 192.168.10.10 is not

allowed

...

 

Although this example was more complex, it serves as a good demonstration of the

power provided by the BrokerFilter class. Just imagine how flexible this plug-in

mechanism is for integrating with existing custom security requirements. This example

was focused on a security example, but many other operations can be customized

by using the pattern illustrated here.

 

这个例子更加复杂一些,用它来示例BrokerFilter类提供的强大功能十分合适.可以设想一下使用这种

插件机制来集成各种自定义的安全需求是多么的灵活.这个例子仅仅关注安全方面的内容,然而使用这种

插件模式可以进行更多的自定义操作.

 

分享到:
评论

相关推荐

    Flamingo(ribbon)、substance6.3 Java皮肤插件

    这两个库在Java开发中尤其受欢迎,因为Java原生的GUI组件通常在视觉上较为简单,而Flamingo和Substance则提供了丰富的样式和自定义选项。 Flamingo库专注于Ribbon UI设计,这是一种用户界面布局模式,最初由...

    最新版windows gradle-6.3-all.zip

    3. 配置IDE集成,如IntelliJ IDEA或Eclipse,需要更新IDE的Gradle插件以支持6.3版本,并在IDE中指定Gradle的安装路径。 四、Gradle 6.3的新特性 1. 改进的依赖管理:Gradle 6.3引入了更智能的依赖解析策略,能够更...

    PHPWind_BIG5_6.3

    7. **插件与API支持**:PHPWind 6.3可能提供更丰富的插件接口和API,方便开发者集成第三方服务或开发自定义功能。 8. **多语言支持**:尽管主要针对BIG5编码,但PHPWind通常也会支持其他语言,如简体中文和英文,...

    gradle-6.3.zip

    Gradle官方提供了一系列预定义的插件,同时也支持自定义插件开发。例如,`apply plugin: 'java'`会为项目启用Java开发的相关功能,包括编译、测试等。 在`gradle-6.3.zip`这个压缩包中,我们可以找到Gradle 6.3版本...

    gradle全集 gradle-6.3-all.zip

    - **自定义任务**:在构建脚本中定义自定义任务,以满足特定的构建需求。 6. **进一步学习资源** - Gradle官网:提供最新的文档、教程和API参考。 - Gradle社区:加入社区讨论,获取帮助和分享经验。 - ...

    VC++源码(notepad++6.3)

    6. **插件系统**:Notepad++具有强大的插件体系,源码中会包含插件接口的设计,以及如何编写和集成自定义功能。 7. **文件操作**:源码将展示如何处理文件的读写操作,包括打开、保存、查找替换和编码转换等常见...

    phpwind6.3树形论坛 无限制版域名可以自由绑定

    管理员在后台可以自定义板块分类,创建和调整板块的层级关系。 2. **域名自由绑定**: 这一版本的一大亮点是支持无限制的域名绑定。管理员可以在后台轻松添加、删除或修改绑定的域名,使论坛能够适应多域名策略,...

    UBB.classicTM 6.3.0.1 中文增强版

    UBB.classicTM 6.3.0.1 中文增强版的核心价值在于其全面升级的功能,不仅提升了论坛的稳定性和安全性,还注重了用户体验,使得论坛管理者能够更高效地运营社区,同时吸引并留住更多用户。无论是对于大型社区还是小型...

    Nessus6.3用户手册(中文版)

    9. 扩展知识:描述如何利用Nessus的插件机制来扩展扫描功能,介绍社区贡献的插件以及如何编写自定义插件。 由于用户手册的具体正文内容未提供,上述知识点是基于对Nessus工具一般性的描述。真正的用户手册会包含更...

    wps vba 插件

    2. **自动化任务**:通过VBA,你可以创建自定义函数,实现批量数据处理,如数据筛选、格式转换等。 3. **用户界面扩展**:VBA可以创建自定义工具栏、菜单和对话框,增强WPS的用户界面体验。 4. **文档保护**:可以...

    Notepad++ 6.3安装文件

    6. **自定义主题**:用户可以根据个人喜好调整编辑器的主题颜色和字体,创建个性化的编辑环境。 在安装Notepad++ 6.3的过程中,`npp.6.3.Installer.exe`是主安装程序文件。执行这个文件将启动安装向导,引导用户...

    ubbthreads v 6.3.0.0

    7. **自定义与扩展**:除了内置功能外,UBB.Threads通常允许用户通过插件和模板系统进行自定义,以适应各种不同的需求和品牌风格。 综上所述,"ubbthreads v 6.3.0.0"是一个强大且灵活的论坛解决方案,为构建和管理...

    EhLib.6.3.Build.6.3.168.rar

    EhLib的主要目标是帮助开发人员创建具有复杂多表头、自定义样式和高级编辑功能的数据展示界面,从而提升应用程序的用户界面体验。 在Delphi中,TDBGrid是最常见的用于显示和编辑数据库数据的控件。然而,它的功能...

    mindmaster6.3 pro版本

    7. **插件系统**:允许用户安装第三方插件,扩展软件的功能。 在提供的压缩包中,文件名为“MindMaster123.exe”,这很可能是MindMaster 6.3 Pro的安装程序。用户下载后,运行此文件即可安装软件。安装过程中,需要...

    maven window下安装包

    第12章:编写自定义插件/12.4 使用自定义插件/12.4.1 在新建的Maven项目中引用自定义插件 第12章:编写自定义插件/12.4 使用自定义插件/12.4.2 测试自定义插件 第12章:编写自定义插件/12.4 使用自定义插件/12.4.3 ...

    ASP网站CMS程序源码——modx 0.9.6.3 简繁中文版实例开发.zip

    开发者可以利用这些插件快速实现特定需求,或者创建自己的插件。 4. **模块和snippet**:MODX的模块和snippet是可重用的代码片段,模块通常包含更完整的功能,而snippet则用于创建简单的函数或动态内容。 5. **...

    webpack-developer-kit:webpack开发工具包,用于即时编写自定义插件和加载程序。 以及EducationExploration工具

    量身定制的超轻量级样板可帮助开发人员了解如何创建自定义加载器和插件。 要求 节点6.3或更高版本(对于本机node --inspect ) 用法 分叉并克隆此仓库,然后运行npm install NPM脚本 已经设置了两个脚本: npm run ...

    禅道项目管理软件6.3版

    625 测试→测试任务改成版本后,后台自定义没有修改对应的名称 629 windows一键安装包控制面板自动生成脚本中禅道访问链接错误 630 专业版windows一键安装包中没有zentao文件夹导致报错 633 上传图片设置图片大小的...

    认识运动和进阶V1.0.0 Uniapp自定义组件

    本教程主要关注的是在 Uniapp 中如何理解和创建自定义组件,这将极大地提升开发效率和代码复用性。 一、Uniapp框架概述 1.1 定义与特点 Uniapp 是基于 Vue.js 开发的,集成了微信小程序、支付宝小程序、百度智能小...

    ASP网站CMS程序源码——modx 0.9.6.3 简繁中文版实例开发.rar

    1. **模板系统**:MODX采用革命性的模板系统,允许开发者使用HTML、CSS和JavaScript轻松创建自定义布局和设计。它支持Smarty模板引擎,使得非程序员也能理解和编辑网站的外观。 2. **资源管理**:MODX中的"资源"是...

Global site tag (gtag.js) - Google Analytics