Chapter 31. 安全

本章讲述HornetQ的安全机制以及如何配置它。要完全关闭安全,只要将hornetq-configuration.xml 文件中的security-enabled参数设为false即可。

出于性能的考虑,安全在HornetQ中被缓存一定的时间。要改变这个时间,需要设置参数 security-invalidation-interval,单位是毫秒。默认值是 10000毫秒。

31.1. 基于角色的地址安全

HornetQ采用了基于角色的安全模型来配置地址的安全以及其队列的安全。

正如在Chapter 8, 使用HornetQ内核解释的那样,HornetQ核心主要由绑定到地址上的队列组成。 消息被发送到地址后,服务器查找与之绑定的队列,并将消息路由到这些队列中。

HornetQ可以基于地址来给队列定义权限。在定义权限时可以使用通配符'#'和 '*'。

队列的权限有7种,它们是:

  • createDurableQueue。允许用户在相应的地址上创建持久的队列。

  • deleteDurableQueue。允许用户在相应的地址上删除相应的持久的队列。

  • createNonDurableQueue。允许用户在相应地址上创建非持久的队列。

  • deleteNonDurableQueue。允许用户在相应地址上删除非持久队列。

  • send。允许用户向相应地址发送消息。

  • consume。允许用户从相应地址上的队列接收消息。

  • manage。允许用户调用管理操作,即向管理地址发关管理消息。

每个权限有一个角色表。如果用户的角色在这个表中,那么它将拥有这个权限。

让我们看个简单的例子。下面是从hornetq-configuration.xml文件或 hornetq-queues.xml文件中提取的安全设置:

<security-setting match="globalqueues.europe.#">
    <permission type="createDurableQueue" roles="admin"/>
    <permission type="deleteDurableQueue" roles="admin"/>
    <permission type="createNonDurableQueue" roles="admin, guest, europe-users"/>
    <permission type="deleteNonDurableQueue" roles="admin, guest, europe-users"/>
    <permission type="send" roles="admin, europe-users"/>
    <permission type="consume" roles="admin, europe-users"/>
</security-setting>            
        

在配置中字符'#'代表"任何单词序列“。单词由'.'字符分隔。 有关通配符的语法的完整说明请参见Chapter 13, 了解 HornetQ 通配符的语法。上面的安全配置对以 "globalqueues.europe."开始的地址有效:

只有具有admin角色的用户才可以创建和删除绑定到以"globalqueues.europe."开始的地址的持久化队列。

具有adminguesteurope-users 角色的用户可以在以开头的地址上创建临时的队列。

任何具有admineurope-users角色的用户可以向以"globalqueues.europe."开头的地址 发送消息,并从绑定到相同地址上的队列接收消息。

安全管理器处理一个用户和它的角色的对应关系。HornetQ本身自带一个用户管理器,能从文件中读取用户的身份信息。 另外HornetQ还可以使用JAAS或JBoss应用服务器的安全管理机制。

有关安全管理器的配置信息,请参见Section 31.4, “更换安全管理器”

在每个xml文件中可以有零个或多个 security-setting。当一组地址有多个这样的设置时, HornetQ总是选取更具体的匹配。

让我们来看一个实例,下面是另一个security-setting

<security-setting match="globalqueues.europe.orders.#">
    <permission type="send" roles="europe-users"/>
    <permission type="consume" roles="europe-users"/>
</security-setting>            
        

在这个security-setting块中,字符串 'globalqueues.europe.orders.#' 要比它之前的字符串'globalqueues.europe.#'更具体。 因此当一个地址与'globalqueues.europe.orders.#'匹配时,它选择这个安全配置。

注意安全设置没有继承性。对于像'globalqueues.europe.orders.plastics'的地址,只要上面的设置 能被采用。即角色europe-users有sendconsume权限。权限 createDurableQueuedeleteDurableQueuecreateNonDurableQueuedeleteNonDurableQueue不会从先前的设置中继承。

由于权限的不可继承,如果我们不在更具体的security-setting设置中给出一个权限,这个权限就是没有的,不会因为继承而带来 麻烦。否则就不可能对一组地址中的部分地址进行如此的设置。

31.2. 安全套接字层(SSL)传输

当消息客户端与服务器端,或服务器之间(比如使用桥的情况)通过一个不信任的网络相互通信时,HornetQ 支持使用加密的安全套接字(SSL)传输数据。

关于SSL的详细配置信息,请参见Chapter 16, 传输层的配置

31.3. 基本用户身份信息(Credentials)

HornetQ自带一个安全管理器(security manager)可以从xml文件中读取用户身份信息,即用户名、 密码、角色信息。该xml文件名为hornetq-users.xml,它必须要在classpath中。

如果你要使用这个安全管理器,就将用户名,密码,角色等信息加入到这个文件中。

让我们看一个例子:

<configuration xmlns="urn:hornetq" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="urn:hornetq ../schemas/hornetq-users.xsd ">
    
    <defaultuser name="guest" password="guest">
        <role name="guest"/>
    </defaultuser>
    
    <user name="tim" password="marmite">
        <role name="admin"/>      
    </user>
    
    <user name="andy" password="doner_kebab">
        <role name="admin"/>
        <role name="guest"/>
    </user>
    
    <user name="jeff" password="camembert">
        <role name="europe-users"/>
        <role name="guest"/>
    </user>
    
</configuration>
        

首先要注意的是defaultuser,它定义的是默认的用户。当客户端创建会话时 没有提供用户名/密码时,就会使用这个用户。根据上述配置,这个默认用户是guest 并且他的角色是guest。一个默认用户可以有多个角色。

另外三个用户中,用户tim具有角色admin。用户andy具有角色adminguest,用户jeff 具有角色europe-usersguest

31.4. 更换安全管理器

如果你不想用默认的安全管理器,可以通过修改配置文件hornetq-beans.xml (或者在运行JBoss应用服务器情况下hornetq-jboss-beans.xml文件)来更换。同时要更换 HornetQSecurityManager bean 的类。

让我们看一段默认bean文件的内容:

           
<bean name="HornetQSecurityManager" 
      class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl">
    <start ignored="true"/>
    <stop ignored="true"/>
</bean>            
        

org.hornetq.spi.core.security.HornetQSecurityManagerImpl 类就是HornetQ服务器的在独立运行时的默认的安全管理器。

HornetQ自带有另外两个安全管理器可供使用。一个是JAAS安全管理器,另一个是用来与JBoss应用服务 器集成的安全管理器。此外,你还可以编写实现你自己的安全管理器。首先要实现 org.hornetq.core.security.SecurityManager接口,再将你的实现 类定义到hornetq-beans.xml文件中即可(或者在JBoss应用服务器中 使用hornetq-jboss-beans.xml文件)。

以下分别介绍这两咱安全管理器

31.5. JAAS安全管理器

JAAS表示“Java认证与授权服务“。它是Java平台标准的一部分。它提供了进行安全认证与授权的通用接口。 它允许你插入自己的安全管理模块。

要配置使用你自己的JAAS安全实现,需要在bean文件中定义JAASSecurityManager。 下面是一个例子:

&lt;bean name="HornetQSecurityManager"
      class="org.hornetq.integration.jboss.security.JAASSecurityManager"&gt;
    &lt;start ignored="true"/&gt;
    &lt;stop ignored="true"/&gt;

    &lt;property name="ConfigurationName"&gt;org.hornetq.jms.example.ExampleLoginModule&lt;/property&gt;
    &lt;property name="Configuration"&gt;
       &lt;inject bean="ExampleConfiguration"/&gt;
    &lt;/property&gt;
    &lt;property name="CallbackHandler"&gt;
       &lt;inject bean="ExampleCallbackHandler"/&gt;
    &lt;/property&gt;
&lt;/bean&gt;
        

注意你需要为JAAS安全管理器提供三个参数:

  • ConfigurationName: LoginModule的名字。

  • Configuration: Configuration的实现。

  • CallbackHandler: CallbackHandler实现,用于用户交互。

31.5.1. 例子

参见Section 11.1.19, “JAAS”。这个例子展示了怎样在HornetQ中配置使用JAAS。

31.6. JBoss 应用服务器安全管理器

JBoss 应用服务器安全管理器适用于当HornetQ运行于JBoss应用服务器内时。它可以与JBoss应用服务器 的安全模型紧密集成。

此安全管理器的类是 org.hornetq.integration.jboss.security.JBossASSecurityManager

要了解如何配置JBoss安全管理器,可以看一眼HornetQ发布包中相关例子中的 hornetq-jboss-beans.xml文件。

31.6.1. 配置客户端登录

JBoss可以配置使用客户登录。JEE的模块如servlet或EJB可以将安全认证信息设置到安全上下文(security context)中, 用于整个调用过程。如果想在HornetQ在发送和接收消息时使用这些认证(credential)信息,需要将参数 allowClientLogin设为true。它会越过HornetQ的身份验证过程并会传播安全上下文(security context)。如果你想要HornetQ使用传播的安全信息进行身份验证,需要同时将参数authoriseOnClientLogin 设为true。

关于客户端登录的详细信息请访问这里

Note

如果消息是以非阻塞方式发送的,那么有可能在消息到达服务器时,调用线程已经结束,安全上下文也被清除了。 所以如果使用安全上下文,需要采用阻塞方式发送消息。

31.7. 集群用户名/密码的配置

为了使集群连接正常工作,每个节点都必须与其它节点相连接。它们连接所使用的默认用户名和密码在正式使用时 一定要做相应的更改,以防止安全隐患。

请参见Chapter 30, 管理了解怎样去做。