236 lines
16 KiB
XML
236 lines
16 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
||
<!-- ============================================================================= -->
|
||
<!-- Copyright © 2009 Red Hat, Inc. and others. -->
|
||
<!-- -->
|
||
<!-- The text of and illustrations in this document are licensed by Red Hat under -->
|
||
<!-- a Creative Commons Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). -->
|
||
<!-- -->
|
||
<!-- An explanation of CC-BY-SA is available at -->
|
||
<!-- -->
|
||
<!-- http://creativecommons.org/licenses/by-sa/3.0/. -->
|
||
<!-- -->
|
||
<!-- In accordance with CC-BY-SA, if you distribute this document or an adaptation -->
|
||
<!-- of it, you must provide the URL for the original version. -->
|
||
<!-- -->
|
||
<!-- Red Hat, as the licensor of this document, waives the right to enforce, -->
|
||
<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent -->
|
||
<!-- permitted by applicable law. -->
|
||
<!-- ============================================================================= -->
|
||
<chapter id="security">
|
||
<title>安全</title>
|
||
<para>本章讲述HornetQ的安全机制以及如何配置它。要完全关闭安全,只要将<literal>hornetq-configuration.xml</literal>
|
||
文件中的<literal>security-enabled</literal>参数设为false即可。</para>
|
||
<para>出于性能的考虑,安全在HornetQ中被缓存一定的时间。要改变这个时间,需要设置参数
|
||
<literal>security-invalidation-interval</literal>,单位是毫秒。默认值是
|
||
<literal>10000</literal>毫秒。</para>
|
||
<section id="security.settings.roles">
|
||
<title>基于角色的地址安全</title>
|
||
<para>HornetQ采用了基于角色的安全模型来配置地址的安全以及其队列的安全。</para>
|
||
<para>正如在<xref linkend="using-core"/>解释的那样,HornetQ核心主要由绑定到地址上的队列组成。
|
||
消息被发送到地址后,服务器查找与之绑定的队列,并将消息路由到这些队列中。</para>
|
||
<para>HornetQ可以基于地址来给队列定义权限。在定义权限时可以使用通配符'<literal>#</literal>'和
|
||
'<literal>*</literal>'。</para>
|
||
<para>队列的权限有7种,它们是:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para><literal>createDurableQueue</literal>。允许用户在相应的地址上创建持久的队列。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>deleteDurableQueue</literal>。允许用户在相应的地址上删除相应的持久的队列。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>createNonDurableQueue</literal>。允许用户在相应地址上创建非持久的队列。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>deleteNonDurableQueue</literal>。允许用户在相应地址上删除非持久队列。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>send</literal>。允许用户向相应地址发送消息。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>consume</literal>。允许用户从相应地址上的队列接收消息。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para><literal>manage</literal>。允许用户调用管理操作,即向管理地址发关管理消息。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<para>每个权限有一个角色表。如果用户的角色在这个表中,那么它将拥有这个权限。</para>
|
||
<para>让我们看个简单的例子。下面是从<literal>hornetq-configuration.xml</literal>文件或
|
||
<literal>hornetq-queues.xml</literal>文件中提取的安全设置:</para>
|
||
<programlisting>
|
||
<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>
|
||
</programlisting>
|
||
<para>在配置中字符'<literal>#</literal>'代表"任何单词序列“。单词由'<literal>.</literal>'字符分隔。
|
||
有关通配符的语法的完整说明请参见<xref linkend="wildcard-syntax"/>。上面的安全配置对以
|
||
"globalqueues.europe."开始的地址有效:</para>
|
||
<para>只有具有<literal>admin</literal>角色的用户才可以创建和删除绑定到以"globalqueues.europe."开始的地址的持久化队列。</para>
|
||
<para>具有<literal>admin</literal>、<literal>guest</literal>或<literal>europe-users</literal>
|
||
角色的用户可以在以开头的地址上创建临时的队列。</para>
|
||
<para>任何具有<literal>admin</literal>或<literal>europe-users</literal>角色的用户可以向以"globalqueues.europe."开头的地址
|
||
发送消息,并从绑定到相同地址上的队列接收消息。</para>
|
||
<para>安全管理器处理一个用户和它的角色的对应关系。HornetQ本身自带一个用户管理器,能从文件中读取用户的身份信息。
|
||
另外HornetQ还可以使用JAAS或JBoss应用服务器的安全管理机制。</para>
|
||
<para>有关安全管理器的配置信息,请参见<xref linkend="change-security-manager"/>。</para>
|
||
<para>在每个xml文件中可以有零个或多个 <literal>security-setting</literal>。当一组地址有多个这样的设置时,
|
||
HornetQ总是选取<emphasis>更具体的</emphasis>匹配。</para>
|
||
<para>让我们来看一个实例,下面是另一个<literal>security-setting</literal>:</para>
|
||
<programlisting>
|
||
<security-setting match="globalqueues.europe.orders.#">
|
||
<permission type="send" roles="europe-users"/>
|
||
<permission type="consume" roles="europe-users"/>
|
||
</security-setting>
|
||
</programlisting>
|
||
<para>在这个<literal>security-setting</literal>块中,字符串
|
||
'globalqueues.europe.orders.#' 要比它之前的字符串'globalqueues.europe.#'更具体。
|
||
因此当一个地址与'globalqueues.europe.orders.#'匹配时,它<emphasis>只</emphasis>选择这个安全配置。</para>
|
||
<para>注意安全设置没有继承性。对于像'globalqueues.europe.orders.plastics'的地址,只要上面的设置
|
||
能被采用。即角色europe-users有<literal
|
||
>send</literal>和<literal>consume</literal>权限。权限
|
||
<literal>createDurableQueue</literal>、 <literal
|
||
>deleteDurableQueue</literal>、<literal>createNonDurableQueue</literal>、<literal
|
||
>deleteNonDurableQueue</literal>不会从先前的设置中继承。</para>
|
||
<para>由于权限的不可继承,如果我们不在更具体的security-setting设置中给出一个权限,这个权限就是没有的,不会因为继承而带来
|
||
麻烦。否则就不可能对一组地址中的部分地址进行如此的设置。</para>
|
||
</section>
|
||
<section>
|
||
<title>安全套接字层(SSL)传输</title>
|
||
<para>当消息客户端与服务器端,或服务器之间(比如使用桥的情况)通过一个不信任的网络相互通信时,HornetQ
|
||
支持使用加密的安全套接字(SSL)传输数据。</para>
|
||
<para>关于SSL的详细配置信息,请参见<xref linkend="configuring-transports"/>。</para>
|
||
</section>
|
||
<section>
|
||
<title>基本用户身份信息(Credentials)</title>
|
||
<para>HornetQ自带一个安全管理器(security manager)可以从xml文件中读取用户身份信息,即用户名、
|
||
密码、角色信息。该xml文件名为<literal>hornetq-users.xml</literal>,它必须要在classpath中。</para>
|
||
<para>如果你要使用这个安全管理器,就将用户名,密码,角色等信息加入到这个文件中。</para>
|
||
<para>让我们看一个例子:</para>
|
||
<programlisting>
|
||
<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>
|
||
</programlisting>
|
||
<para>首先要注意的是<literal>defaultuser</literal>,它定义的是默认的用户。当客户端创建会话时
|
||
没有提供用户名/密码时,就会使用这个用户。根据上述配置,这个默认用户是<literal>guest</literal>
|
||
并且他的角色是<literal>guest</literal>。一个默认用户可以有多个角色。</para>
|
||
<para>另外三个用户中,用户<literal>tim</literal>具有角色<literal
|
||
>admin</literal>。用户<literal>andy</literal>具有角色<literal
|
||
>admin</literal>和<literal>guest</literal>,用户<literal>jeff</literal>
|
||
具有角色<literal>europe-users</literal>和<literal>guest</literal>。</para>
|
||
</section>
|
||
<section id="change-security-manager">
|
||
<title>更换安全管理器</title>
|
||
<para>如果你不想用默认的安全管理器,可以通过修改配置文件<literal>hornetq-beans.xml</literal>
|
||
(或者在运行JBoss应用服务器情况下<literal
|
||
>hornetq-jboss-beans.xml</literal>文件)来更换。同时要更换
|
||
<literal>HornetQSecurityManager</literal> bean 的类。</para>
|
||
<para>让我们看一段默认bean文件的内容:</para>
|
||
<programlisting>
|
||
<bean name="HornetQSecurityManager"
|
||
class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl">
|
||
<start ignored="true"/>
|
||
<stop ignored="true"/>
|
||
</bean>
|
||
</programlisting>
|
||
<para><literal>org.hornetq.spi.core.security.HornetQSecurityManagerImpl</literal>
|
||
类就是HornetQ服务器的在独立运行时的默认的安全管理器。</para>
|
||
<para>HornetQ自带有另外两个安全管理器可供使用。一个是JAAS安全管理器,另一个是用来与JBoss应用服务
|
||
器集成的安全管理器。此外,你还可以编写实现你自己的安全管理器。首先要实现
|
||
<literal>org.hornetq.core.security.SecurityManager</literal>接口,再将你的实现
|
||
类定义到<literal>hornetq-beans.xml</literal>文件中即可(或者在JBoss应用服务器中
|
||
使用<literal>hornetq-jboss-beans.xml</literal>文件)。</para>
|
||
<para>以下分别介绍这两咱安全管理器</para>
|
||
</section>
|
||
<section>
|
||
<title>JAAS安全管理器</title>
|
||
<para>JAAS表示“Java认证与授权服务“。它是Java平台标准的一部分。它提供了进行安全认证与授权的通用接口。
|
||
它允许你插入自己的安全管理模块。</para>
|
||
<para>要配置使用你自己的JAAS安全实现,需要在bean文件中定义<literal>JAASSecurityManager</literal>。
|
||
下面是一个例子:</para>
|
||
<programlisting><![CDATA[
|
||
<bean name="HornetQSecurityManager"
|
||
class="org.hornetq.integration.jboss.security.JAASSecurityManager">
|
||
<start ignored="true"/>
|
||
<stop ignored="true"/>
|
||
|
||
<property name="ConfigurationName">org.hornetq.jms.example.ExampleLoginModule</property>
|
||
<property name="Configuration">
|
||
<inject bean="ExampleConfiguration"/>
|
||
</property>
|
||
<property name="CallbackHandler">
|
||
<inject bean="ExampleCallbackHandler"/>
|
||
</property>
|
||
</bean>
|
||
]]></programlisting>
|
||
<para>注意你需要为JAAS安全管理器提供三个参数:</para>
|
||
<itemizedlist>
|
||
<listitem>
|
||
<para>ConfigurationName: <literal>LoginModule</literal>的名字。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>Configuration: <literal>Configuration</literal>的实现。</para>
|
||
</listitem>
|
||
<listitem>
|
||
<para>CallbackHandler: <literal>CallbackHandler</literal>实现,用于用户交互。</para>
|
||
</listitem>
|
||
</itemizedlist>
|
||
<section>
|
||
<title>例子</title>
|
||
<para>参见<xref linkend="examples.jaas"/>。这个例子展示了怎样在HornetQ中配置使用JAAS。</para>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>JBoss 应用服务器安全管理器</title>
|
||
<para>JBoss 应用服务器安全管理器适用于当HornetQ运行于JBoss应用服务器内时。它可以与JBoss应用服务器
|
||
的安全模型紧密集成。</para>
|
||
<para>此安全管理器的类是 <literal
|
||
>org.hornetq.integration.jboss.security.JBossASSecurityManager</literal>。</para>
|
||
<para>要了解如何配置JBoss安全管理器,可以看一眼HornetQ发布包中相关例子中的
|
||
<literal>hornetq-jboss-beans.xml</literal>文件。</para>
|
||
<section>
|
||
<title>配置客户端登录</title>
|
||
<para>JBoss可以配置使用客户登录。JEE的模块如servlet或EJB可以将安全认证信息设置到安全上下文(security context)中,
|
||
用于整个调用过程。如果想在HornetQ在发送和接收消息时使用这些认证(credential)信息,需要将参数
|
||
<literal>allowClientLogin</literal>设为true。它会越过HornetQ的身份验证过程并会传播安全上下文(security
|
||
context)。如果你想要HornetQ使用传播的安全信息进行身份验证,需要同时将参数<literal>authoriseOnClientLogin</literal>
|
||
设为true。</para>
|
||
<para>关于客户端登录的详细信息请访问<ulink
|
||
url="http://community.jboss.org/wiki/ClientLoginModule">这里</ulink>。 </para>
|
||
<note><para>如果消息是以非阻塞方式发送的,那么有可能在消息到达服务器时,调用线程已经结束,安全上下文也被清除了。
|
||
所以如果使用安全上下文,需要采用阻塞方式发送消息。</para></note>
|
||
</section>
|
||
</section>
|
||
<section>
|
||
<title>集群用户名/密码的配置</title>
|
||
<para>为了使集群连接正常工作,每个节点都必须与其它节点相连接。它们连接所使用的默认用户名和密码在正式使用时
|
||
一定要做相应的更改,以防止安全隐患。</para>
|
||
<para>请参见<xref linkend="management"/>了解怎样去做。</para>
|
||
</section>
|
||
</chapter>
|