安全指南
Preface
部分 I. JBoss 企业版应用程序平台 6 的安全性
第 1 章 简介
1.1. 关于安全性
1.2. 安全性和系统管理员
1.3. 安全性和 J2EE 开发人员
- 应用程序开发人员 - 负责开发级别的安全性以及定义角色、规则和商业逻辑到应用程序逻辑。
- 应用程序组装者 - 负责确保完成 EAR 和 WAR 的打包,将跨应用程序的易损性降至最低。
- 应用程序部署者 - 负责保护 EAR 的部署且分配和维护访问控制列表。
部分 II. 保证平台的安全
第 2 章 安全子系统
2.1. 关于安全子系统
如果 Deep Copy 模式被禁用(默认),复制安全数据结构会产生一个对原始结构的引用,而不是复制整个数据结构。这个行为效率更高,但在具有相同标识符的多个线程通过冲刷或登出操作清除主题时容易受数据损坏的影响。
你可以设置系统范围的安全属性,它们应用在 java.security.Security class
。
安全域(Security Domain)是一系列 Java 验证和授权服务(Java Authentication and Authorization Service,JAAS)的声明式安全配置,一个或多个应用程序用它来控制验证、授权、审计和映射。有三个默认的安全域:jboss-ejb-policy
、jboss-web-policy
和 other
。你也可以按照应用程序的需要创建安全域。
2.2. 关于安全子系统的结构
例 2.1. 安全子系统配置示例
<subsystem xmlns="urn:jboss:domain:security:1.2"> <security-management> ... </security-management> <security-domains> <security-domain name="other" cache-type="default"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="RealmUsersRoles" flag="required"> <module-option name="usersProperties" value="${jboss.domain.config.dir}/application-users.properties"/> <module-option name="rolesProperties" value="${jboss.domain.config.dir}/application-roles.properties"/> <module-option name="realm" value="ApplicationRealm"/> <module-option name="password-stacking" value="useFirstPass"/> </login-module> </authentication> </security-domain> <security-domain name="jboss-web-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> <security-domain name="jboss-ejb-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> </security-domains> <vault> ... </vault> </subsystem>
<security-management>
、<subject-factory>
和 <security-properties>
元素没有出现在默认配置里。从 JBoss EAP 6.1 开始已启用了 <subject-factory>
和 <security-properties>
元素。
2.3. 关于加密
2.4. 关于声明式安全性
2.5. 配置安全子系统
- <security-management>
- 这部分内容覆盖了安全子系统的高层行为。每个设置都是可选的。除了 Deep Copy 模式,须该这些设置的任何一个都是不寻常的。
选项 描述 deep-copy-subject-mode 指定是否复制或链接安全令牌以用于额外的线程安全。authentication-manager-class-name 指定一个要使用的其他的 AuthenticationManager 实现的类名。default-callback-handler-class-name 指定和登录模块一起使用的 CallbackHandler 实现的全局类名。authorization-manager-class-name 指定一个要使用的其他的 AuthorizationManager 实现的类名。audit-manager-class-name 指定一个要使用的其他的 AuditManager 实现的类名。identity-trust-manager-class-name 指定一个要使用的其他的 IdentityTrustManager 实现的类名。mapping-manager-class-name 指定一个要使用的 MappingManager 实现的类名。 - <subject-factory>
- 主题工厂(Subject factory)控制主题实例的创建。它可以使用验证管理者来检验调用者。主题工厂的主要用途是为了 JCA 组件建立主题。你通常不需要修改它。
- <security-domains>
- 保存多个安全域的容器元素。安全域可能包含关于验证、授权、映射、审计模块以及 JASPI 验证和 JSSE 配置的信息。你的应用程序可以指定一个安全域来管理它的安全信息。
- <security-properties>
- 包含在 java.security.Security 类上设置的属性的名字和值。
第 3 章 管理接口的安全性
3.1. 保护管理接口
在测试环境里,我们通常在由管理控制台、管理 CLI 和其他 API 实现组成的管理接口上不设置安全层来运行 JBoss EAP 6 。这可以允许快速的开发和配置修改。
3.2. 默认的用户安全性配置
在 EAP 6 里,所有的管理接口都默认是有设置安全性的。这个安全性采取两种形式:
- 本地接口通过本地客户和服务器间的 SASL 合约设置安全性。这个安全机制基于客户访问本地文件系统的能力。这是因为访问本地文件系统会允许客户添加用户或修改配置以阻挠其他安全机制。如果对文件系统的物理访问可以实现,那么其他安全机制就是多余的。这个机制以四个步骤实现:
注意
即使你通过 HTTP 连接本地主机,HTTP 访问仍会视作远程的。- 客户发送一条消息给服务器,它包含一个用本地 SASL 机制验证的请求。
- 服务器生成一个一次性的令牌,将其写入到唯一的文件里,然后发送具有完整文件路径的消息给客户。
- 客户从文件里读取令牌并发送给服务器,检验它是否具有对文件系统的本地访问权限。
- 服务器验证令牌并删除这个文件。
- 远程客户,包括本地 HTTP 客户,使用基于区的安全性。带有使用管理接口远程配置 EAP 权限的默认区是
ManagementRealm
。我们提供了一个脚本,允许你添加用户到这个区(或者你创建的区)。请参考《JBoss EAP 6 安装指南》的 Getting Started 章节。对于每个用户,用户名,hased 密码,以及区都存储在文件里。- 独立服务器
JPP_HOME/standalone/configuration/mgmt-users.properties
即使注明了mgmt-users.properties
的内容,这个文件仍应该作为敏感文件对待。我们推荐将其文件权限设置为600
,这样除了文件所有者,其他人都没有读或写的权限。
3.3. 高级管理接口配置概述
EAP_HOME/domain/configuration/host.xml
或 EAP_HOME/standalone/configuration/standalone.xml
里的管理接口配置控制主机控制器进程绑定哪些网络接口,哪种管理接口是可用的,哪种类型的验证系统用来验证每个接口上的用户。本主题讨论了如何配置管理接口以适应你的运行环境。
<management>
元素组成。首先定义安全区和转出连接,然后再将它们作为属性应用到管理接口。
<security-realms>
<outbound-connections>
<management-interfaces>
安全区(Security Realm)负责允许通过管理 API、管理 CLI 和基于 web 的管理控制台管理 JBoss EAP 的用户的验证和授权。
ManagementRealm
和 ApplicationRealm
。每个安全区都使用一个 -users.properties
文件来存储用户和哈希密码,以及一个 -roles.properties
来存储用户和角色间的映射。相同也包含了对启用了 LDAP 的安全区的支持。
注意
一些安全区连接至外部接口,如 LDAP 服务器。转出连接(Outbound connection)定义了如何创建这种连接。预定义的连接类型,ldap-connection
,设置了连接 LDAP 服务器并验证凭证的所有必需和可选的属性。
管理接口包含如何连接和配置 JBoss EAP 的属性。这样的信息包括命名网络接口、端口、安全区和其他关于接口的可配置信息。默认安装里包含了两个接口:
http-interface
是基于 web 的管理控制台的配置。native-interface
是命令行管理 CLI 和类 REST 管理 API 的配置。
3.4. 禁用 HTTP 管理接口
注意
console-enabled-attribute
为 false
,而无需完全禁用这个接口。
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=console-enabled,value=false)
例 3.1. 读取 HTTP 接口的配置
/host=master/core-service=management/management-interface=http-interface/:read-resource(recursive=true,proxies=false,include-runtime=false,include-defaults=true)
{
"outcome" => "success",
"result" => {
"console-enabled" => true,
"interface" => "management",
"port" => expression "${jboss.management.http.port:9990}",
"secure-port" => undefined,
"security-realm" => "ManagementRealm"
}
}
例 3.2. 删除 HTTP 接口
/host=master/core-service=management/management-interface=http-interface/:remove
例 3.3. 重新创建 HTTP 接口
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=console-enabled,value=true)
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=interface,value=management)
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=port,value=${jboss.management.http.port:9990})
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=ManagementRealm)
3.5. 从默认的安全区删除无提示验证
JBoss EAP 6 的默认安装包含一个用于本地管理 CLI 用户的无提示验证(Silent Authentication)方法。这允许本地用户无需用户名或密码验证就可以访问管理 CLI。启用这个功能是为了方便,并协助本地用户无需验证就可以运行管理 CLI 脚本。它是一个非常有用的功能,特别是对本地配置的访问通常也会让用户可以添加自己的细节或禁用安全检查。
security-realm
部分里的 local
来实现。这适用于独立服务器的 standalone.xml
或受管域的 host.xml
。你应该只在理解了对特定服务器配置的影响后才考虑删除 local
元素。
local
元素。
例 3.4. security-realm
里的 local
元素示例
<security-realms> <security-realm name="ManagementRealm"> <authentication> <local default-user="$local"/> <properties path="mgmt-users.properties" relative-to="jboss.server.config.dir"/> </authentication> </security-realm> <security-realm name="ApplicationRealm"> <authentication> <local default-user="$local" allowed-users="*"/> <properties path="application-users.properties" relative-to="jboss.server.config.dir"/> </authentication> <authorization> <properties path="application-roles.properties" relative-to="jboss.server.config.dir"/> </authorization> </security-realm> </security-realms>
过程 3.1. 从默认的安全区删除无提示验证
用管理 CLI 删除无提示验证
按要求从管理区和应用程序区删除local
元素。- 从管理区删除
local
元素。对于独立服务器
/core-service=management/security-realm=ManagementRealm/authentication=local:remove
对于受管域
/host=HOST_NAME/core-service=management/security-realm=ManagementRealm/authentication=local:remove
- 从应用程序区删除
local
元素。对于独立服务器
/core-service=management/security-realm=ApplicationRealm/authentication=local:remove
对于受管域
/host=HOST_NAME/core-service=management/security-realm=ApplicationRealm/authentication=local:remove
无提示验证从 ManagementRealm
和 ApplicationRealm
里删除了。
3.6. 禁用对 JMX 子系统的远程访问
/profile=default
部分。对于独立服务器,请完全删除命令的这个部分。
注意
例 3.5. 从 JMX 子系统删除远程连接器。
/profile=default/subsystem=jmx/remoting-connector=jmx/:remove
例 3.6. 删除 JMX 子系统
/profile=default/subsystem=jmx/:remove
3.7. 为管理接口配置安全区
这个例子展示了 ManagementRealm
安全区的默认配置。它使用了一个名为 mgmt-users.properties
的文件来保存其配置信息。
例 3.7. 默认的 ManagementRealm
/host=master/core-service=management/security-realm=ManagementRealm/:read-resource(recursive=true,proxies=false,include-runtime=false,include-defaults=true)
{
"outcome" => "success",
"result" => {
"authorization" => undefined,
"server-identity" => undefined,
"authentication" => {"properties" => {
"path" => "mgmt-users.properties",
"plain-text" => false,
"relative-to" => "jboss.domain.config.dir"
}}
}
}
下面的命令创建了一个名为 TestRealm
的安全区并为相关的配置文件设置名称和目录。
例 3.8. 编写安全区
/host=master/core-service=management/security-realm=TestRealm/:add
/host=master/core-service=management/security-realm=TestRealm/authentication=properties/:add(path=TestUsers.properties, relative-to=jboss.domain.config.dir)
添加了安全区后,将其名称作为引用提供给管理接口。
例 3.9. 在管理接口里添加一个安全区
host=master/core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=TestRealm)
3.8. 用于敏感字符串的密码库
3.8.1. 关于保护明码文件里的敏感字符
3.8.2. 创建一个 Java 密钥库来存储敏感信息
前提条件
keytool
命令必须可用。它时 JRE 提供的命令。请找到这个文件所在的位置,在红帽企业版 Linux 里,它是/usr/bin/keytool
。
过程 3.2. 设置 Java 密钥库
创建一个目录来存储你的密钥库和其他加密的信息。
创建一个目录来存储你的密钥库和其他加密的信息。这个过程的剩余部分将假设这个目录是/home/USER/vault/
。确定
keytool
要使用的参数。确定下列参数:- alias
- 别名是 vault 或其他存储在密钥库里的数据的唯一标识符。这个过程结尾的命令示例里的别名是
vault
。别名是区分大小写的。 - keyalg
- 用于加密的算法。默认是
DSA
。这个过程里的例子使用了RSA
。请查看你的 JRE 和操纵系统的文档,看那种选择是可用的。 - keysize
- 加密密钥的大小影响了通过 brute force 解密的难度。默认的密钥大小是 1024。它必须是 512 到 1024 只见,且是 64 的倍数。这个过程里的例子使用了
1024
。 - keystore
- 密钥库是一个保存加密信息以及如何解密的信息的数据库。如果你没有指定密钥库,默认的密钥库是你的主目录下的
.keystore
。当第一次添加数据到密钥库时,它会被创建。这个过程里的例子使用了vault.keystore
密钥库。
keystore
命令有很多其他选项。更多的细节,请参考你的 JRE 或操纵系统的文档。确定
keystore
命令会询问的问题的答案。keystore
需要下列信息来填充密钥库条目:- 密钥库密码
- 当你创建一个密钥库时,你必须设置密码。为了和将来的密钥库一起使用,你需要提供密码。请选择一个你可以记住的强密码。密钥库的安全性取决于密码以及它所在的文件系统和操纵系统的安全性。
- 密钥密码(可选)
- 除了密钥库密码,你可以为每个保存的密钥指定一个密码。每次使用这个密钥时都需要输入密码。通常这个功能不会被使用。
- 名和姓
- 这和列表里余下的信息可以有助于唯一标识密钥并将其放入一个其他密钥的层次结构里。它完全可以不是一个名字,但应该是两个单词,而且是唯一的。这个过程里的例子使用了
Accounting Administrator
。按照目录的术语,它成为了证书的通用名称(common name)。 - 机构内部门(Organizational unit)
- 这是一个标识谁在使用证书的单词。它可以是应用程序或商业单元。这个过程里的例子使用了
AccountingServices
。通常,组或应用程序使用的所有密钥库都使用相同的机构内部门。 - 机构
- 这通常是一个代表你的机构名称的单词。它通常在机构使用的所有证书里都保持相同。这个例子使用了
MyOrganization
。 - 城市或自治区
- 你的城市
- 州或省
- 你的州或省,或者相等的地区
- 国家
- 两个字母的国家代码
所有这些信息将创建一个密钥库和证书的层次结构,确保它们使用一致而唯一的命名结构。运行
keytool
命令,提供你收集的信息。例 3.10.
keystore
命令的输入和输出的例子。$ keytool -genkey -alias vault -keyalg RSA -keysize 1024 -keystore /home/USER/vault/vault.keystore Enter keystore password: vault22 Re-enter new password:vault22 What is your first and last name? [Unknown]:
Accounting Administrator
What is the name of your organizational unit? [Unknown]:AccountingServices
What is the name of your organization? [Unknown]:MyOrganization
What is the name of your City or Locality? [Unknown]:Raleigh
What is the name of your State or Province? [Unknown]:NC
What is the two-letter country code for this unit? [Unknown]:US
Is CN=Accounting Administrator, OU=AccountingServices, O=MyOrganization, L=Raleigh, ST=NC, C=US correct? [no]:yes
Enter key password for <vault> (RETURN if same as keystore password):
在 /home/USER/vault/
目录里创建了一个名为 vault.keystore
的文件。它保存了一个名为 vault
的密钥,这个密钥将为用来为 JBoss EAP 保存加密字符串,如密码。
3.8.3. 设置密钥库密码的掩码并初始化密码库
前提条件
EAP_HOME/bin/vault.sh
应用程序需要可以通过命令行界面来访问。
运行
vault.sh
命令。运行EAP_HOME/bin/vault.sh
。输入0
启动新的交互式会话。输入保存加密文件的目录。
这个目录应该比较安全,但 JBoss EAP 需要能够访问它。如果你按照 第 3.8.2 节 “创建一个 Java 密钥库来存储敏感信息” 进行,你的密钥库应该位于主目录的vault/
里。这个例子使用了目录/home/USER/vault/
。注意
不要忘记目录名后面的斜杠。根据操作系统来使用/
或\
。输入密钥库的路径。
输入密钥库文件的完整路径。这个例子使用了/home/USER/vault/vault.keystore
。加密密钥库的密码。
下面的步骤加密了密钥库的密码,所以你可以在配置文件和应用程序里安全地使用它了。输入密钥库的密码。
遇到提示时,输入密钥库的密码。输入一个 salt 值。
输入 8 个字符的 salt 值。这个 salt 值和下面的迭代计数用于创建哈希值。输入迭代计数。
输入迭代计数的值。记录密码掩码信息。
密码掩码、salt 和迭代计数都输出在标准输出里。将其记录在一个安全的位置。攻击者可能用它们来破解密码。输入 vault 的别名。
遇到提示时,输入 vault 的别名。如果你按照 第 3.8.2 节 “创建一个 Java 密钥库来存储敏感信息” 来创建 vault,那么别名应该是vault
。
退出交互式控制台。
输入exit
来退出交互式控制台。
你的密钥库密码已设置掩码,可用于配置文件和部署了。此外,你的 vault 已配置完全且可以使用了。
3.8.4. 配置 JBoss EAP 来使用密码库
在你可以在配置文件里为密码设置掩码和其他敏感属性之前,你需要让 JBoss EAP 知晓存储和破解密码的密码库。请按照下列步骤来启用这个功能。
过程 3.3. 设置密码库
确定这个命令的正确的值。
确定下列参数的值,这个命令将用它们来创建密钥库。关于创建密钥库的信息,请参考下列主题:第 3.8.2 节 “创建一个 Java 密钥库来存储敏感信息” 和 第 3.8.3 节 “设置密钥库密码的掩码并初始化密码库”。参数 描述 KEYSTORE_URL 密钥库文件的 URL 的文件系统路径,它通常类似于vault.keystore
。KEYSTORE_PASSWORD 用来访问密钥库的密码。这个值应该被标记。KEYSTORE_ALIAS 密钥库的名称。SALT 用来加密和解密密钥库值的 Salt。ITERATION_COUNT 运行加密算法的次数。ENC_FILE_DIR 密钥库命令运行的目录路径。通常是包含密码库的目录。host (managed domain only) 你在配置的主机的名称使用管理 CLI 来启用密码库。
根据使用的是受管域还是独立服务器配置,分别运行下列命令。用这个步骤里第一步里的值替换命令里的值。受管域
/host=YOUR_HOST/core-service=vault:add(vault-options=[("KEYSTORE_URL" => "PATH_TO_KEYSTORE"), ("KEYSTORE_PASSWORD" => "MASKED_PASSWORD"), ("KEYSTORE_ALIAS" => "ALIAS"), ("SALT" => "SALT"),("ITERATION_COUNT" => "ITERATION_COUNT"), ("ENC_FILE_DIR" => "ENC_FILE_DIR")])
独立服务器
/core-service=vault:add(vault-options=[("KEYSTORE_URL" => "PATH_TO_KEYSTORE"), ("KEYSTORE_PASSWORD" => "MASKED_PASSWORD"), ("KEYSTORE_ALIAS" => "ALIAS"), ("SALT" => "SALT"),("ITERATION_COUNT" => "ITERATION_COUNT"), ("ENC_FILE_DIR" => "ENC_FILE_DIR")])
下面是带有假定值的命令示例:/core-service=vault:add(vault-options=[("KEYSTORE_URL" => "/home/user/vault/vault.keystore"), ("KEYSTORE_PASSWORD" => "MASK-3y28rCZlcKR"), ("KEYSTORE_ALIAS" => "vault"), ("SALT" => "12438567"),("ITERATION_COUNT" => "50"), ("ENC_FILE_DIR" => "/home/user/vault/")])
JBoss EAP 已配置好通过密码库来破解掩码字符串。要添加字符串到库里并在配置里使用它们,请参考下列主题:第 3.8.5 节 “在 Java 密钥库里保存和获取加密的敏感字符串”。
3.8.5. 在 Java 密钥库里保存和获取加密的敏感字符串
在普通文本配置文件里包含密码和其他敏感字符串是不安全的。JBoss EAP 包括了在加密的密钥库里存储并 mask 这些敏感字符串,以及在配置文件里使用 mask 值。
前提条件
EAP_HOME/bin/vault.sh
应用程序需要可以通过命令行界面来访问。
过程 3.4. 设置 Java 密钥库
运行
vault.sh
命令。运行EAP_HOME/bin/vault.sh
。输入0
启动新的交互式会话。输入保存加密文件的目录。
如果你遵循 第 3.8.2 节 “创建一个 Java 密钥库来存储敏感信息”,你的密钥库将位于主目录里的vault/
下。在多数情况下,将所有加密信息保存在相同的位置是有意义的。这个例子使用了/home/USER/vault/
。注意
不要忘记目录名后面的斜杠。根据操作系统来使用/
或\
。输入密钥库的路径。
输入密钥库文件的完整路径。这个例子使用了/home/USER/vault/vault.keystore
。输入密钥库密码、Vault 名、Sale 和迭代计数。
遇到提示时,输入密钥库密码、Vault 名、Sale 和迭代计数。然后将执行握手操作。选择保存密码的选项。
选择选项0
来保存密码或其他敏感字符串。输入这个值。
遇提示时,将这个值输入两次。如果两次的值不匹配,会提示你再次输入。输入 Vault Block。
输入 Vault Block,输入属性名称。
输入你在保存的属性的名称。一个例子就是password
。结果类似于下面的信息表示这个属性已经被保存了。
Attribute Value for (ds_ExampleDS, password) saved
记录关于加密字符串的信息。
标准输出的信息将显示 vault block、属性名称、共享密钥和在配置里使用字符串的建议。请在安全的地方记录这些信息。下面是输出示例。******************************************** Vault Block:ds_ExampleDS Attribute Name:password Shared Key:N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0 Configuration should be done as follows: VAULT::ds_ExampleDS::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0 ********************************************
在你的配置里使用加密的字符串。
在你的配置里使用前面步骤里的字符串来替代普通文本字符串。下面是使用加密密码的数据源。... <subsystem xmlns="urn:jboss:domain:datasources:1.0"> <datasources> <datasource jndi-name="java:jboss/datasources/ExampleDS" enabled="true" use-java-context="true" pool-name="H2DS"> <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url> <driver>h2</driver> <pool></pool> <security> <user-name>sa</user-name> <password>${VAULT::ds_ExampleDS::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0}</password> </security> </datasource> <drivers> <driver name="h2" module="com.h2database.h2"> <xa-datasource-class>org.h2.jdbcx.JdbcDataSource</xa-datasource-class> </driver> </drivers> </datasources> </subsystem> ...
你可以在允许表达式的任何域或独立配置文件里使用加密字符串。注意
要检查某个子系统里是否允许表达式,请在这个子系统里运行下列 CLI 命令:/host=master/core-service=management/security-realm=TestRealm:read-resource-description(recursive=true)
在这个命令的输出里,查找expressions-allowed
参数的值。如果它为 true,你可以在这个特定子系统的配置里使用表达式。在密钥库里保存了字符串后,请使用下列语法用加密字符串替代任何明文字符串。${VAULT::<replaceable>VAULT_BLOCK</replaceable>::<replaceable>ATTRIBUTE_NAME</replaceable>::<replaceable>ENCRYPTED_VALUE</replaceable>}
下面是一个例子,其 Vault Block 是ds_ExampleDS
,而属性是password
。<password>${VAULT::ds_ExampleDS::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0}</password>
3.8.6. 存储和解析应用程序里的敏感字符串
JBoss EAP 的 Configuration 元素支持使用安全库(Security Vault)机制根据 Java 密钥库里保存的值来解析加密的字符串。你可以在自己的应用程序里添加对这个功能的支持。
在执行这个过程之前,请确保保存库文件的目录是存在的。将其保存在什么位置是无所谓的,只要执行 JBoss EAP 的用户有读写这些文件的权限。这个例子将 vault/
目录放到 /home/USER/vault/
目录里。这个库本身也是 vault/
里一个名为 vault.keystore
的文件。
例 3.11. 添加密码字符串到库里
EAP_HOME/bin/vault.sh
命令添加这个字符串到库里。下面的屏幕输出包含了这个命令的完整过程和结果。用户输入的值被高亮显示。出于格式的考虑,我们删除了一些输出。在 Microsoft Windows 里,这个命令是 vault.bat
。请注意,在 Microsoft Windows 里,文件路径要使用 \
来分隔,而不是 /
。
[user@host bin]$ ./vault.sh ********************************** **** JBoss Vault ******** ********************************** Please enter a Digit:: 0: Start Interactive Session 1: Remove Interactive Session 2: Exit0
Starting an interactive session Enter directory to store encrypted files:/home/user/vault/
Enter Keystore URL:/home/user/vault/vault.keystore
Enter Keystore password:...
Enter Keystore password again:...
Values match Enter 8 character salt:12345678
Enter iteration count as a number (Eg: 44):25
Enter Keystore Alias:vault
Vault is initialized and ready for use Handshake with Vault complete Please enter a Digit:: 0: Store a password 1: Check whether password exists 2: Exit0
Task: Store a password Please enter attribute value:sa
Please enter attribute value again:sa
Values match Enter Vault Block:DS
Enter Attribute Name:thePass
Attribute Value for (DS, thePass) saved Please make note of the following: ******************************************** Vault Block:DS Attribute Name:thePass Shared Key:OWY5M2I5NzctYzdkOS00MmZhLWExZGYtNjczM2U5ZGUyOWIxTElORV9CUkVBS3ZhdWx0 Configuration should be done as follows: VAULT::DS::thePass::OWY5M2I5NzctYzdkOS00MmZhLWExZGYtNjczM2U5ZGUyOWIxTElORV9CUkVBS3ZhdWx0 ******************************************** Please enter a Digit:: 0: Store a password 1: Check whether password exists 2: Exit2
VAULT
开始的行。
例 3.12. 使用 vaulted 密码的 servlet
package vaulterror.web; import java.io.IOException; import java.io.Writer; import javax.annotation.Resource; import javax.annotation.sql.DataSourceDefinition; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; /*@DataSourceDefinition( name = "java:jboss/datasources/LoginDS", user = "sa", password = "sa", className = "org.h2.jdbcx.JdbcDataSource", url = "jdbc:h2:tcp://localhost/mem:test" )*/ @DataSourceDefinition( name = "java:jboss/datasources/LoginDS", user = "sa", password = "VAULT::DS::thePass::OWY5M2I5NzctYzdkOS00MmZhLWExZGYtNjczM2U5ZGUyOWIxTElORV9CUkVBS3ZhdWx0", className = "org.h2.jdbcx.JdbcDataSource", url = "jdbc:h2:tcp://localhost/mem:test" ) @WebServlet(name = "MyTestServlet", urlPatterns = { "/my/" }, loadOnStartup = 1) public class MyTestServlet extends HttpServlet { private static final long serialVersionUID = 1L; @Resource(lookup = "java:jboss/datasources/LoginDS") private DataSource ds; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Writer writer = resp.getWriter(); writer.write((ds != null) + ""); } }
3.9. LDAP
3.9.1. 关于 LDAP
3.9.2. 在管理接口里使用 LDAP 进行验证
- 创建一个到 LDAP 服务器的转出连接。
- 创建一个启用 LDAP 的安全区。
- 在管理接口里引用新的安全区。
LDAP 转出连接允许下列属性:
属性 | 必需的 | 描述 |
---|---|---|
名称 | 是 |
标识这个连接的名称。这个名称用在安全区定义里。
|
url | 是 |
目录服务器的 URL 地址。
|
search-dn | 是 |
授权执行搜索的用户的全限定可区分名称(Distinguished Name,DN)。
|
search-credentials | 是 |
用户授权执行搜索的密码。
|
initial-context-factory | 否 |
当建立连接时使用的初始上下文。默认为
com.sun.jndi.ldap.LdapCtxFactory 。
|
例 3.13. 添加 LDAP 转出连接
- 搜索 DN:
cn=search,dc=acme,dc=com
- 搜索凭证:
myPass
- URL:
ldap://127.0.0.1:389
/host=master/core-service=management/ldap-connection=ldap_connection/:add(search-credential=myPass,url=ldap://127.0.0.1:389,search-dn="cn=search,dc=acme,dc=com")
例 3.14. 代表 LDAP 转出连接的 XML 片段
<outbound-connections> <ldap name="ldap_connection" url="ldap://127.0.0.1:389" search-dn="cn=search,dc=acme,dc=com" search-credential="myPass" /> </outboundconnections>
管理接口可以针对 LDAP 服务器而不是默认的基于属性文件的安全区进行验证。LDAP 验证器将首先建立一个和远程目录服务器的连接,然后使用传入验证系统的用户名来执行搜索以找到 LDAP 记录的全限定可区分名称(Distinguished Name,DN)。新的连接将以用户的 DN 为凭证以及用户提供的密码来建立。如果这个针对 LDAP 服务器的验证成功,DN 就被证明为有效的。
- connection
<outbound-connections>
里定义的连接的名称,用来连接 LDAP 目录。- base-dn
- 用户开始搜索的上下文的可区分的名称。
- recursive
- 搜索是否应该在 LDAP 目录树里进行递归,或者只搜索指定的上下文。默认为
false
。 - user-dn
- 保存可区分名称的用户的属性。它会被用来测试验证。默认为
dn
。 - 子元素是
username-filter
或advanced-filter
中的一个。 username-filter
采用一个名为attribute
的属性,它的值是保存用户名的 LDAP 属性的名称,如userName
或sambaAccountName
。advanced-filter
采用一个名为filter
的属性。这个属性包含以标准 LDAP 语法编写的过滤器队列。请小心地将&
字符修改为&
。下面是一个过滤器的例子:(&(sAMAccountName={0})(memberOf=cn=admin,cn=users,dc=acme,dc=com))
After escaping the ampersand character, the filter appears as:(&(sAMAccountName={0})(memberOf=cn=admin,cn=users,dc=acme,dc=com))
例 3.15. 代表启用了 LDAP 的安全区的 XML 片段
- connection -
ldap_connection
- base-dn -
cn=users,dc=acme,dc=com
. - username-filter -
attribute="sambaAccountName"
<security-realm name="TestRealm"> <authentication> <ldap connection="ldap_connection" base-dn="cn=users,dc=acme,dc=com"> <username-filter attribute="sambaAccountName" /> </ldap> </authentication> </security-realm>
警告
例 3.16. 添加 LDAP 安全区
/host=master/core-service=management/security-realm=ldap_security_realm/authentication=ldap:add(base-dn="DC=mycompany,DC=org", recursive=true, username-attribute="MyAccountName", connection="ldap_connection")
在创建了安全区后,你需要在管理接口的配置里引用它。管理接口将使用安全区来进行 HTTP digest 验证。
例 3.17. 应用安全区到 HTTP 接口里
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=TestRealm)
第 4 章 Java 安全性管理者
4.1. 关于 Java 安全性管理者
Java 安全性管理者是一个管理 Java 虚拟机(JVM)sandbox 外部边界的类,它控制代码在 JVM 里执行时如何和外部的资源交互。当 Java 安全性管理者被激活时,Java API 在执行许多有潜在风险的操作之前会检查 Java 安全性管理者以获得批准。
4.2. 关于 Java 安全管理者策略
以不同代码类别表示的一系列权限。Java 安全管理者将应用程序的动作请求和安全策略进行比较。如果某个动作是策略所允许的,那么安全管理者将允许这个动作执行。如果这个动作是策略所不允许的,那么将拒绝这个动作的执行。安全策略可以根据代码的位置或签名来定义权限。
java.security.manager
和 java.security.policy
配置的。
4.3. 在 Java 安全管理者里运行 JBoss EAP
domain.sh
或 standalone.sh
脚本。下面的过程会指引你配置实例以在 Java 安全管理者里运行 JBoss EAP。
前提条件
- 在执行下列过程之前,你需要用 JDK 里包含的
policytool
编写一个安全策略。这个过程假定你的策略位于EAP_HOME/bin/server.policy
。 - 在编辑配置文件之前,域或独立服务器必须完全停止。
过程 4.1. 编辑配置文件
打开配置文件。
打开配置文件进行编辑。根据你使用的是域还是独立服务器,这个文件位于两个位置中的一个。它不是用来启动服务器或域的可执行文件。受管域
EAP_HOME/bin/domain.conf
独立服务器
EAP_HOME/bin/standalone.conf
在文件末尾添加 Java 选项。
在文件结尾添加下列行。你可以修改-Djava.security.policy
值来制定安全策略的准确位置。这个值应该只有一行,且不能中断。你也可以修改-Djava.security.debug
、指定调试级别来记录更多或更少的信息。完整的选项是failure,access,policy
。JAVA_OPTS="$JAVA_OPTS -Djava.security.manager -Djboss.home.dir=$PWD/.. -Djava.security.policy==$PWD/server.policy -Djava.security.debug=failure"
启动域或服务器。
正常地启动域或服务器。
4.4. 编写 Java 安全性管理者策略
多数 JDK 和 JRE 版本里都包含一个 policytool
程序,它用于创建和编辑 Java 安全管理者安全策略。关于 policytool
的详细信息请访问 http://docs.oracle.com/javase/6/docs/technotes/tools/。
安全策略由下列配置元素组成:
- CodeBase
- 产生代码的 URL 位置(不包括主机和域信息)。这个参数是可选的。
- SignedBy
- 密钥库里用来引用签名者(其私有密钥用于为代码签名)的别名。这可以是单个的值,也可以是用逗号隔开的值的列表。如果忽略它,签名的缺席与否都不会影响 Java 安全管理者。
- Principals
- principal_type/principal_name 对的列表,它必须出现在执行线程的 principal 集里。Principal 条目是可选的。如果忽略它,则表示 “任何 principals“。
- 权限
- 权限是赋予代码的访问许可。许多权限是作为 Java EE 5 规格的一部分提供的。这个文档只涵盖了 JBoss EAP 提供的额外的权限。
过程 4.2. 设置新的 Java 安全性管理者策略
启动
policytool
.以下列方式之一启动policytool
工具。红帽企业版 Linux
在 GUI 或命令行提示下,运行/usr/bin/policytool
。Microsoft Windows Server
从开始菜单或 Java 安装的bin\
里运行policytool.exe
。在不同系统里,其位置可能会不一样。
创建一个新的策略。
要创建新的策略,请选择。添加你需要的参数,然后点击 。编辑现有的策略
从现有的策略列表里选择策略,并选择按钮。然后根据需要编辑相关参数。删除现有的策略。
从现有的策略列表里选择策略,并选择按钮。
JBoss EAP 专有的权限
- org.jboss.security.SecurityAssociation.getPrincipalInfo
- 提供对
org.jboss.security.SecurityAssociation
getPrincipal()
和getCredential()
方法的访问。使用这个运行时权限涉及的风险是可以看到当前的线程调用者和凭证。 - org.jboss.security.SecurityAssociation.getSubject
- 提供对
org.jboss.security.SecurityAssociation
getSubject()
方法的访问。 - org.jboss.security.SecurityAssociation.setPrincipalInfo
- 提供对
org.jboss.security.SecurityAssociation
setPrincipal()
,setCredential()
,setSubject()
,pushSubjectContext()
和popSubjectContext()
方法的访问。 - org.jboss.security.SecurityAssociation.setServer
- 提供对
org.jboss.security.SecurityAssociation
setServer
方法的访问。使用这个运行时权限涉及的风险是可以启用或禁用调用 principal 和凭证的多线程存储。 - org.jboss.security.SecurityAssociation.setRunAsRole
- 提供对
org.jboss.security.SecurityAssociation
pushRunAsRole
,popRunAsRole
,pushRunAsIdentity
和popRunAsIdentity
方法的访问。使用这个运行时权限涉及的风险是可以修改当前调用者的 run-as 角色 principal。 - org.jboss.security.SecurityAssociation.accessContextInfo
- 提供对
org.jboss.security.SecurityAssociation
accessContextInfo
和accessContextInfo
的 getter 和 setter 方法的访问。这允许你设置和获取当前安全上下文信息。 - org.jboss.naming.JndiPermission
- 提供对指定 JNDI 树路径里的文件和目录或递归至全部文件和子目录的特殊权限。JndiPermission 由一个路径名和相对于文件或目录的一系列有效权限组成。可用的权限包括:
- bind
- rebind
- unbind
- lookup
- list
- listBindings
- createSubcontext
- all
Pathnames ending in/*
indicate that the specified permissions apply to all files and directories of the pathname. Pathnames ending in/-
indicate recursive permissions to all files and subdirectories of the pathname. Pathnames consisting of the special token <<ALL BINDINGS>> matches any file in any directory. - org.jboss.security.srp.SRPPermission
- 保护对敏感 SRP 信息(如私有会话密钥和私有密钥)访问的自定义权限类。这个权限没有定义任何动作。
getSessionKey
目标提供对 SRP 协商导致的私有会话密钥的访问。对这个密钥的访问允许你加密和解密已经用这个会话密钥加密的消息。 - org.hibernate.secure.HibernatePermission
- 这个权限类提供对于安全 Hibernate 会话的基本权限。这个属性的目标是实体名称。可用的动作包括:
- insert
- delete
- update
- read
- * (all)
- org.jboss.metadata.spi.stack.MetaDataStackPermission
- 提供一个自定义权限类来控制调用者如何和元数据栈进行交互。可用的权限是:
- modify
- push (onto the stack)
- pop (off the stack)
- peek (onto the stack)
- * (all)
- org.jboss.config.spi.ConfigurationPermission
- 配置属性的安全设置。只定义权限目标名称,不定义动作。这个属性的目标包括:
- <property name> (the property this code has permission to set)
- * (all properties)
- org.jboss.kernel.KernelPermission
- 对于内核配置的安全访问。只定义权限目标,不定义动作。这个属性的目标包括:
- access (to the kernel configuration)
- configure (implies access)
- * (all)
- org.jboss.kernel.plugins.util.KernelLocatorPermission
- 对于内核的安全访问。只定义权限目标,不定义动作。这个属性的目标包括:
- kernel
- * (all)
4.5. 调试安全管理者策略
java.security.debug
选项配置和安全相关的信息的级别。java -Djava.security.debug=help
命令将产生具有完整调试选项的帮助信息。当解决和安全相关的故障而完全不知道原因时,设置调试级别为 all
是很有用的。但对于普通的用途而言,这会产生过多的信息。一般默认的选项是 access:failure
。
过程 4.3. 启用普通调试
这个过程将启用普通级别的和安全相关的调试信息。
在服务器配置文件里添加下列行。- 如果 JBoss EAP 实例运行在受管域里,这一行将添加到
bin/domain.conf
()或bin/domain.conf.bat
(Windows)。 - 如果 JBoss EAP 实例作为独立服务器运行,这一行将添加到
bin/standalone.conf
()或bin\standalone.conf.bat
(Windows)。
Linux
JAVA_OPTS="$JAVA_OPTS -Djava.security.debug=access:failure"
Windows
JAVA_OPTS="%JAVA_OPTS% -Djava.security.debug=access:failure"
启用了普通级别的和安全相关的调试信息。
第 5 章 安装补丁
5.1. 关于补丁机制
- 计划中的更新:作为现有产品的小版本、次要版本、主要版本升级的一部分。
- 异步更新:作为一次性的补丁,它在现有产品的常规更新周期之外发布。
- 发现漏洞的容易程度?
- 如果出现漏洞,会造成什么样的损害?
- 有无其他降低漏洞影响的因素(如防火墙、Security-Enhanced Linux 、编译器指令等)?
5.2. 订阅补丁邮件列表(Patch Mailing List)
红帽的 JBoss 团队维护了一个用于中间件安全通知的邮件列表。本节涵盖订阅这个列表所需的步骤。
前提条件
- 无
过程 5.1. 订阅 JBoss Watch List
- 点击下列链接进入 JBoss Watch 邮件列表页面:JBoss Watch Mailing List。
- 在 Subscribing to Jboss-watch-list 部分输入你的电子邮件地址。
- [你可能也想输入你的名字和密码。这完全由你决定,但我们不推荐这么做。]
- 点击按钮启动订阅过程。
- 你可以访问 JBoss Watch Mailing List Archives 来浏览邮件列表的归档。
在确认你的电子邮件账号之后,你将订阅 JBoss 补丁邮件列表来接收安全相关的通知。
5.3. 以 ZIP 形式安装补丁
JBoss 安全补丁以两种形式发布:ZIP(用于所有产品)和 RPM(用于产品的子集)。JBoss 的程序错误修复补丁只以 ZIP 形式发布。本节描述了适用 ZIP 形式安装补丁(安全或程序错误修复)的步骤。
前提条件
- 对红帽客户门户的有效访问和订阅。
- 对以 ZIP 形式安装的 JBoss 产品的当前订阅。
过程 5.2. 通过 ZIP 方式对 JBoss 产品应用补丁
警告
- 通过订阅 JBoss Watch 邮件列表或浏览 JBoss Watch 邮件列表归档来获得安全补丁的通知。
注意
JBoss Watch 邮件列表只通知安全补丁。 - 阅读安全补丁的勘误并确认它可以应用于你的 JBoss 产品。
- 如果安全补丁适用于你的 JBoss 产品,请用这个链接从红帽客户门户下载补丁文件。
- 从客户门户下载的 ZIP 文件会包含修复安全问题或程序错误所需的所有文件。下载这个补丁 ZIP 文件到和 JBoss 产品相同的位置。
- 在安装 JBoss 产品的位置解压补丁文件,覆盖现有的版本。
JBoss 产品用 ZIP 文件方式更新了最新的补丁。
5.4. 以 RPM 形式安装补丁
JBoss 安全补丁以两种形式发布:ZIP(用于所有产品)和 RPM(用于产品的子集)。JBoss 的程序错误修复补丁只以 ZIP 形式发布。本节描述了适用 RPM 形式安装补丁的步骤。RPM 更新方法只用来发布安全性异步补丁和小/次要/主要版本的产品更新。
前提条件
- 对红帽网络的有效订阅。
- 对以 RPM 形式安装的 JBoss 产品的当前订阅。
过程 5.3. 通过 RPM 方式对 JBoss 产品应用补丁
警告
- 通过订阅 JBoss Watch 邮件列表或浏览 JBoss Watch 邮件列表归档来获得安全补丁的通知。
- 阅读安全补丁的勘误并确认它可以应用于你的 JBoss 产品。
- 如果安全补丁适用于你的 JBoss 产品,请用这个链接从红帽客户门户下载包含在勘误里的 PRM 软件包。
- 请使用
或类似的命令来安装补丁。yum update
JBoss 产品用 RPM 软件包方式更新了最新的补丁。
5.5. JBoss 安全补丁的严重性和影响级别
严重性 | 描述 |
---|---|
严重(Critical) |
这个级别是容易被未授权的远程攻击者利用的漏洞,它可能导致系统破解(任意代码执行)而无需用户干预。这些漏洞易受蠕虫病毒利用。要求经验证的远程用户、本地用户或不太可能的配置的漏洞不会被归类于严重(Critical)影响级别。
|
重要(Important) |
这个级别的漏洞可以轻易地破解资源的机密性、完整性或能力。这些漏洞允许本地用户获取权限,允许未验证的远程用户查看本应该被验证保护的资源、执行任意的代码,或者允许本地或远程用户导致服务拒绝问题。
|
中等(Moderate) |
这个级别的漏洞可能更难被利用,但仍然会导致资源的机密性、完整性或能力某种程度的破解。这些漏洞可能产生严重或重要的影响,但根据技术评估,会较不容易被利用或影响不太可能的配置。
|
低(Low) |
其他具有安全性影响的漏洞都归类于这个级别。这些漏洞在不太可能的情况下才会被利用,或者即使被利用也只会造成最小的后果。
|
例 5.1. CVSS v2 影响分数
C:N/I:P/A:C
第 6 章 安全域
6.1. 关于安全域
6.2. 关于 Picketbox
- 第 6.5 节 “关于授权” 和访问控制
- 第 6.9 节 “关于安全性映射” 和 principal、角色、属性
6.3. 关于验证
6.4. 配置安全域的验证
过程 6.1. 为安全域设置验证
打开安全域的详细视图。
点击管理控制台由上角的 Profiles 标签。在受管域里,从 Profile 视图左上角的 Profile 选择框里选择要修改的配置集。点击左侧的 Security 并点击展开菜单里的 Security Domains。点击你要编辑的安全域的 View 链接。进入验证子系统配置。
如果还未选择的话,点击视图顶部的 Authentication 标签。配置区域分成两部分:Login Modules 和 Details。登录模块是配置的基本单元。安全域可以包含多个登录模块,每个都包括几个属性和选项。添加一个验证模块。
点击 Add 按钮来添加一个 JAAS 验证模块。输入相关的内容。Code 是模块的类名。Flags 控制模块如何和相同安全域里的其他验证模块交互。对标签的解释Java EE 6 规格提供了安全域的标签的解释。下面的列表来自 http://docs.oracle.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html#AppendixA。关于更消息的信息,请参考这个文档。
标签 详情 Required 登录模块是验证成功所必需的。如果成功或失败,验证都仍会继续处理登录模块列表。Requisite 登录模块是验证成功所必需的。如果成功,验证将继续处理登录模块列表。如果失败,控制权马上返回给应用程序(验证不会继续处理登录模块列表)。Sufficient 登录模块不是验证成功所必需的。如果成功,控制权马上返回给应用程序(验证不会继续处理登录模块列表)。如果失败,验证将继续处理登录模块列表。Optional 登录模块不是验证成功所必需的。如果成功或失败,验证都仍会继续处理登录模块列表。在你添加了模块时,你可以通过屏幕上的 Details 里的 按钮修改它的 Code 或Flags。请确保选择了 Attributes 标签页。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Login Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,点击它的键来进行修改。你可以使用 按钮来删除选项。
你的验证模块已添加至安全域,且马上可为使用安全域的应用程序所用。
jboss.security.security_domain
模块选项
在默认情况下,安全域里定义的每个登录模块都会自动添加一个 jboss.security.security_domain
模块选项。这个选项会给检查是否只定义了已知选项的登录模块带来问题。IBM Kerberos 登录模块 com.ibm.security.auth.module.Krb5LoginModule
就是其中之一。
true
来禁用添加这个模块选项的行为。请添加下列内容到你的启动参数里。
-Djboss.security.disable.secdomain.option=true
6.5. 关于授权
6.6. 配置安全域里的授权
过程 6.2. 在安全域里设置授权
打开安全域的详细视图。
点击管理控制台由上角的 Profiles 标签。在受管域里,从 Profile 视图左上角的 Profile 选择框里选择要修改的配置集。点击左侧的 Security 并点击展开菜单里的 Security Domains。点击你要编辑的安全域的 View 链接。进入授权子系统配置。
如果还未选择的话,点击视图顶部的 Authorization 标签。配置区域分成两部分:Policies 和 Details。登录模块是配置的基本单元。安全域可以包含几个授权策略,每个都包括几个属性和选项。添加策略
点击 Add 按钮来添加一个 JAAS 授权策略模块。输入相关的内容。Code 是模块的类名。Flags 控制模块如何和相同安全域里的其他授权模块交互。对标签的解释Java EE 6 规格提供了安全域的标签的解释。下面的列表来自 http://docs.oracle.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html#AppendixA。关于更消息的信息,请参考这个文档。
标签 详情 要求的 登录模块是授权成功所必需的。如果成功或失败,授权都仍会继续处理登录模块列表。Requisite 登录模块是授权成功所必需的。如果成功,授权将继续处理登录模块列表。如果失败,控制权马上返回给应用程序(授权不会继续处理登录模块列表)。Sufficient 登录模块不是授权成功所必需的。如果成功,控制权马上返回给应用程序(授权不会继续处理登录模块列表)。如果失败,授权将继续处理登录模块列表。Optional 登录模块不是授权成功所必需的。如果成功或失败,授权都仍会继续处理登录模块列表。在你添加了模块时,你可以通过屏幕上的 Details 里的 按钮修改它的 Code 或Flags。请确保选择了 Attributes 标签页。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Login Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,点击它的键来进行修改。你可以使用 按钮来删除选项。
你的授权模块已添加至安全域,且马上可为使用安全域的应用程序所用。
6.7. 关于安全性审计
6.8. 配置安全审计
过程 6.3. 在安全域里设置安全审计
打开安全域的详细视图。
点击管理控制台由上角的 Profiles 标签。在独立服务器里,标签页是 Profile。在受管域里,从 Profile 视图左上角的 Profile 选择框里选择要修改的配置集。点击左侧的 Security 并点击展开菜单里的 Security Domains。点击你要编辑的安全域的 View 链接。进入审计子系统配置。
如果还未选择的话,点击视图顶部的 Audit 标签。配置区域分成两部分:Provider Modules 和 Details。提供者模块(Provider Module)是配置的基本单元。安全域可以包含多个提供者模块,每个都包括几个属性和选项。添加一个提供者模块。
点击 Add 按钮来添加一个提供者模块。在 Code 里输入提供者模块的类名。在你添加了模块时,你可以通过屏幕上的 Details 里的 按钮修改它的 Code。请确保选择了 Attributes 标签页。检验你的模块是否可以运行
审计模块的目的是提供一个在安全子系统里监控事件的途径。这种监控可以通过写入日志文件、电子邮件通知或其他可度量的审计机制来实现。例如,JBoss EAP 默认包含了LogAuditProvider
模块。如果按照上面的步骤启用,这个审计模块会将安全通知写入EAP_HOME
目录里的log
子目录下的audit.log
文件里。要检验上面的步骤是否可以在LogAuditProvider
上下文里运行,你可以执行一个可能触发通知的动作并检查审计日志文件。关于安全审计提供者模块的完整列表,请参考 第 A.4 节 “包括的安全审计供应商模块”。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,你可以使用 按钮来删除它,或者用正确的选项点击 按钮再次添加它。
你的安全审计模块已添加至安全域,且马上可为使用安全域的应用程序所用。
6.9. 关于安全性映射
6.10. 在安全域里配置安全映射
过程 6.4. 在安全域里设置安全映射
打开安全域的详细视图。
点击管理控制台由上角的 Profiles 标签。在独立服务器里,标签页是 Profile。在受管域里,从 Profile 视图左上角的 Profile 选择框里选择要修改的配置集。点击左侧的 Security 并点击展开菜单里的 Security Domains。点击你要编辑的安全域的 View 链接。进入映射子系统配置。
如果还未选择的话,点击视图顶部的 Mapping 标签。配置区域分成两部分:Modules 和 Details。映射模块是配置的基本单元。安全域可以包含多个映射模块,每个都包括几个属性和选项。添加一个模块。
点击 Add 按钮来添加一个安全映射模块。输入模块的相关内容。Code 是模块的类名。Type 字段表示这个模块执行的映射的类型。所允许的值有 principal、role、attribute 和 credential。在你添加了模块时,你可以通过屏幕上的 Details 里的 按钮修改它的 Code 或Type。请确保选择了 Attributes 标签页。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,点击 Remove 标签键来删除它,并用新的值再次添加它。你可以使用 按钮来删除选项。
你的安全映射模块已添加至安全域,且马上可为使用安全域的应用程序所用。
第 7 章 SSL 加密
7.1. 关于 SSL 加密
7.2. 对 JBoss EAP Web 服务器实施 SSL 加密
许多 web 应用程序都要求对客户端和服务器间的连接进行 SSL 加密,这也被称为 HTTPS
连接。你可以通过这个过程对服务器或服务器组启用 HTTPS
。
前提条件
- 你需要一系列 SLL 加密密钥和加密证书。你可以从证书签名机构购买或者使用命令行工具来生成。关于使用红帽企业版 Linux 工具来生成加密密钥,请参考 第 7.3 节 “生成 SSL 密钥和证书”。
- 你需要知道你的环境和设置的下列细节:
- 你的证书文件的完整目录名和路径
- 你的加密密钥的密码。
- 你需要运行管理 CLI 并连接到域控制器或独立服务器。
注意
/profile=default
删除。
过程 7.1. 配置 JBoss Web 服务器以使用 HTTPS
添加新的 HTTPS 连接器。
执行下列管理 CLI 命令来修改配置。这会创建一个新的加密连接器,名为HTTPS
。它使用https
模式、https
套接字绑定(默认为8443
端口),且被设置为安全的。例 7.1. 管理 CLI 命令
/profile=default/subsystem=web/connector=HTTPS/:add(socket-binding=https,scheme=https,protocol=HTTP/1.1,secure=true)
配置 SSL 加密证书和密钥。
执行下列 CLI 命令来配置你的 SSL 证书,请用自己的值来替换例子里的值。这个例子假设密钥库被复制到服务器的配置目录,对于受管域来说,也就是EAP_HOME/domain/configuration/
。例 7.2. 管理 CLI 命令
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration:add(name=https,certificate-key-file=${jboss.server.config.dir}/keystore.jks,password=SECRET, key-alias=KEY_ALIAS)
关于连接器的 SSL 属性参数的完整列表,请参考 第 7.4 节 “SSL 连接器引用”。部署应用程序。
部署一个使用你已经配置好的配置集的应用程序到服务器组。如果你使用的是独立服务器,将这个应用程序部署至服务器。它的 HTTP 请求将使用新的 SSL 加密的连接。
7.3. 生成 SSL 密钥和证书
前提条件
- 你需要
keytool
工具,任何 JDK 都提供它。红帽企业版 Linux 上的 OpenJDK 将这个命令安装在/usr/bin/keytool
。 - 请理解
keytool
命令的语法和参数。这个过程将使用非常浅显的说明,因为对 SSL 证书或keytool
命令的深入讨论都超出了本文档的范畴。
过程 7.2. 生成 SSL 密钥和证书
用公共和私有密钥生成密钥库。
运行下列命令来当前目录里生成带有别名jboss
的名为server.keystore
的密钥库。keytool -genkey -alias jboss -keyalg RSA -keystore server.keystore -storepass mykeystorepass --dname "CN=jsmith,OU=Engineering,O=mycompany.com,L=Raleigh,S=NC,C=US"
下表描述了用于 keytool 命令的参数:参数 描述 -genkey
keytool
命令生成包含公共和私有密钥的密钥对。-alias
密钥库的别名。这个值是任意的,但别名 jboss
是 JBoss Web 服务器使用的默认值。-keyalg
密钥对的生成算法。这个例子里是 RSA
。-keystore
密钥库文件的名称和位置。默认的位置是当前的目录。你可以选择任意名字。在这个例子里是 server.keystore
。-storepass
这个密码用于针对密钥库进行验证,从而读取密钥。这个密码长度必须至少为 6 且在访问时密钥库时提供。在这个例子里,我们使用 mykeystorepass
。如果你忽略这个参数,在执行命令时你将被提示输入它。-keypass
这是实际密钥的密码。注意
由于实现的限制,它必须和库的密码相同。--dname
引号括起的描述密钥的可区分名称的字符串,如"CN=jsmith,OU=Engineering,O=mycompany.com,L=Raleigh,C=US"。这个字符串是下列组件的组合: CN
- 常用名或主机名。如果主机名是 "jsmith.mycompany.com",那么CN
就是 "jsmith"。OU
- 机构单元,如 "Engineering"。O
- 机构名称,如 "mycompany.com"。L
- 地区,如 "Raleigh" 或 "London"。S
- 州或省,如 "NC"。这个参数是可选的。C
- 两个字符的国家代码,如 "US" 或 "UK"。
当你执行上述命令时,你会被提示输入下列信息:- 如果你在命令行没有使用
-storepass
参数,你会被要求输入密钥库的密码。在下一次提示时再次输入新密码。 - 如果你在命令行没有使用
-keypass
参数,你会被要求输入密钥密码。按 Enter 将其设置为和密钥密码相同的值。
当命令执行完毕时,server.keystore
文件包含了带有别名jboss
的单个密钥。检验这个密钥。
通过下列命令检验这个密钥是否正常工作。keytool -list -keystore server.keystore
你会被提示输入密钥库密码。密钥库的内容将被显示(这个例子里是名为jboss
的单个密钥)。请注意jboss
密钥的类型是keyEntry
。这表示密钥库包含这个密钥的公共和私有条目。生成一个证书签名请求。
运行下列命令使用步骤一里创建的密钥库里的公共密钥来生成一个证书签名请求。keytool -certreq -keyalg RSA -alias jboss -keystore server.keystore -file certreq.csr
系统会提示你输入密码以针对密钥库进行验证。然后keytool
命令将在当前工作目录里创建一个名为certreq.csr
的证书签名请求。测试新生成的证书。
通过下列命令测试证书的内容。openssl req -in certreq.csr -noout -text
证书细节将被显示。可选:提交证书到证书认证机构(CA)。
证书机构(Certificate Authority,CA)可以验证你的证书,它被第三方的客户认为是可靠的。CA 向你提供一个签名的证书,还有一个或多个可选的中间证书。可选:从密钥库导出自签名的证书
如果你只需要用来进行测试或内部使用,你可以使用自签名的证书。你可以从密钥库导出在步骤一创建的证书:keytool -export -alias jboss -keystore server.keystore -file server.crt
系统会提示你输入密码以针对密钥库进行验证。名为server.crt
的自签名的证书将在当前工作目录里创建。导入已签名的证书以及任何中间的证书。
按照 CA 里说明的顺序导入每个证书。对于每个要导入的证书,请用实际的文件名替换intermediate.ca
或server.crt
。如果你的证书未作为独立的文件提供,请为每个证书创建一个独立的文件,并将其内容粘贴到文件里。注意
你的已签名的证书和密钥都是有价值的资产。请小心地在服务器间传递。keytool -import -keystore server.keystore -alias intermediateCA -file intermediate.ca
keytool -import -alias jboss -keystore server.keystore -file server.crt
测试你的证书是否已经成功导入。
运行下列命令,遇提示时输入密钥库密码。密钥库的内容将被显示,证书将是列表里的一部分。keytool -list -keystore server.keystore
你签名的证书现在已包含在密钥库里了,它可用来加密 SSL 连接,包括 HTTPS web 服务器通讯。
7.4. SSL 连接器引用
default
配置集的受管域的。按照你的需要修改这个配置集名称(对于受管域),或者忽略命令行的 /profile=default
部分(对于独立服务器)。
属性 | 描述 | CLI 命令 |
---|---|---|
名称 |
SSL 连接器的显示名称。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=name,value=https) |
verify-client |
设置为
true 表示在接受连接前需要客户的有效证书链。如果你希望 SSL 栈来请求客户证书,可以将其设为 want 。设置为 false (默认值)表示不要求证书链,除非客户请求被使用 CLIENT-CERT 验证的安全约束保护的资源。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=verify-client,value=want) |
verify-depth |
中间证书发行者在决定客户是否具有有效证书前检查的最多次数。默认值是
10 。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=verify-depth,value=10) |
certificate-key-file |
保存服务器证书的密钥库文件的完整文件路径和名称。对于 JSSE 加密,这个证书文件将是唯一的,而 OpenSSL 则使用几个文件。默认值是运行 JBoss EAP 的用户的主目录下的
.keystore 。如果你的 keystoreType 没有使用文件,请将这个参数设置为空字符串。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=certificate-key-file,value=../domain/configuration/server.keystore) |
certificate-file |
如果你使用 OpenSSL 加密,请设置这个参数的值为包含服务器证书的文件的路径。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=certificate-file,value=server.crt) |
password |
用于信任库和密钥库的密码。默认值是
changeit ,你必须修改它,使其匹配密钥库的密码,从而可以正常使用配置。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=password,value=changeit) |
protocol |
要使用的 SSL 协议的版本。支持的值包括
SLv2 、SSLv3 、TLSv1 、SSLv2+SSLv3 和 ALL 。默认的是 ALL 。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=protocol,value=ALL) |
cipher-suite |
用逗号隔开的所允许的加密密码的列表。JSSE 的默认 JVM 包含不应该使用的弱密码。这个例子只列出了两个可能的密码,但实际的例子可能使用更多。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=cipher-suite, value="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA") |
key-alias |
用于密钥库里服务器证书的别名。默认值是
jboss 。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=key-alias,value=jboss) |
truststore-type |
信任库的类型。不同的密钥库包括
PKCS12 和 Java 的标准 JKS 。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=truststore-type,value=jks) |
keystore-type |
密钥库的类型那个。不同的密钥库类型包括
PKCS12 和 Java 的标准 JKS 。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=keystore-type,value=jks) |
ca-certificate-file |
包含 CA 证书的文件。对于 JSSE 是
truststoreFile ,并对密钥库使用相同密码。ca-certificate-file 文件被用来检验客户证书。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=certificate-file,value=ca.crt) |
ca-certificate-password |
用于
ca-certificate-file 的证书密码。在下面的例子里,请用自己的掩码密码替换其中的密码。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=ca-certificate-password,value=MASKED_PASSWORD) |
ca-revocation-url |
包含撤销列表的文件或 URL。它指向
crlFile (JSSE )或 SSLCARevocationFile (SSL)。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=ca-revocation-url,value=ca.crl) |
session-cache-size |
SSL 会话缓存的大小。默认值是
0 ,它禁用会话缓存。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=session-cache-size,value=100) |
session-timeout |
在缓存的 SSLSession 过期前的秒数。默认值为
86400 秒,也就是 24 小时。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=session-timeout,value=43200) |
第 8 章 安全区
8.1. 关于安全区
ManagementRealm
存储用于管理 API 的用户、密码和角色信息,它提供管理 CLI 和基于 web 的管理控制台的功能。它也为管理 JBoss EAP 自身提供了一个验证系统。如果你的应用程序需要用用于管理 API 的相同商业规则来验证,你也可以使用ManagementRealm
。ApplicationRealm
存储用于 Web 应用程序和 EJB 的用户、密码和角色信息。
REALM-users.properties
存储用户名和 hashed 密码。REALM-users.roles
存储用户和角色的映射。
domain/configuration/
和 standalone/configuration/
目录里。这些文件由 add-user.sh
或 add-user.bat
同时写入。当你运行这命令时,你的第一个决定是添加新用户到哪个区。
8.2. 添加新的安全区
运行管理 CLI。
运行jboss-cli.sh
或jboss-cli.bat
命令并连接服务器。创建新的安全区。
运行下列命令在域控制器或独立服务器上创建一个名为MyDomain
的安全区。/host=master/core-service=management/security-realm=MyDomainRealm:add()
创建对将保存新角色信息的属性文件的引用。
运行下列命令创建一个名为myfile.properties
的文件,它将包含附属新角色的属性。注意
新创建的属性文件不是由内含的add-user.sh
和add-user.bat
脚本管理的。它必须进行外部管理。/host=master/core-service=management/security-realm=MyDomainRealm/authentication=properties:add(path=myfile.properties)
你的新安全区已被创建了。当你添加用户和角色到这个新的安全区时,信息将被存储在默认安全区外的一个单独的文件里。你可以用自己的应用程序或过程来管理这个新的文件。
8.3. 添加用户到安全区里
运行
add-user.sh
或add-user.bat
命令。打开一个命令行界面(command-line interface,CLI)。进入EAP_HOME/bin/
目录。如果你运行的是红帽企业版 LInux 或其他类 Unix 系统,请运行add-user.sh
。如果你运行的是 Microsoft Windows 服务器,则请运行add-user.bat
。选择是否添加管理用户或应用程序用户。
对于这个过程,输入b
来添加应用程序用户。选择用户所添加至的安全区。
在默认的情况下,唯一可用的安全区是ApplicationRealm
。如果你已经添加了一个自定义区,你可以输入它的名称。在提示时输入用户名、密码和角色。
在提示时输入想要的用户名、密码和可选角色。输入yes
确认选择或no
取消修改。所作修改将被写入到安全区的每个属性文件里。
第 9 章 子系统配置
9.1. 事务子系统的配置
9.1.1. 为 JTS 事务配置 ORB
注意
full
和 full-ha
配置集。在独立服务器里,你可以使用 standalone-full.xml
或 standalone-full-ha.xml
配置。
过程 9.1. 使用管理控制台配置 ORB
查看配置集设置。
从管理控制台的右上角选择 Profiles (受管域) 或 Profile(独立服务器)。如果你使用了受管域,请在左上角选择 full 或 full-ha 配置集。修改 Initializers 设置
展开左侧的 Subsystems 菜单,展开 Container 子菜单并点击 JacORB。在主屏幕上出现的表单里,选择 Initializers 标签页并点击 Edit 按钮。通过设置 Security 为on
来启用安全拦截器。要启用 JTS 里的 ORB,请设置 Transaction Interceptors 值为on
,而不是默认的spec
。关于这些值的详细解释,请点击表单里的 Need Help? 链接。在完成编辑后请点击 Save。高级的 ORB 配置
关于高级的配置选项,请参考表单的其他部分。每个部分都包含一个关于参数详细解释的 Need Help? 链接。
你可以使用管理 CLI 配置 ORB 的每个方面。下面的命令配置初始器为与上面过程里使用管理控制台相同的值。这是 JTS 里 ORB 的最小配置。
/profile=full
部分。
例 9.1. 启用安全拦截器
/profile=full/subsystem=jacorb/:write-attribute(name=security,value=on)
例 9.2. 启用 JTS 里的 ORB
/profile=full/subsystem=jacorb/:write-attribute(name=transactions,value=on)
9.2. JMS 配置
9.2.1. 对 HornetQ 配置属性的引用
read-resource
操作开放可配置或可查看的属性。
例 9.3. 示例
[standalone@localhost:9999 /] /subsystem=messaging/hornetq-server=default:read-resource
属性 | 示例值 | 类型 |
---|---|---|
allow-failback | true | BOOLEAN |
async-connection-execution-enabled | true | BOOLEAN |
backup | false | BOOLEAN |
cluster-password | somethingsecure | STRING |
cluster-user | HORNETQ.CLUSTER.ADMIN.USER | STRING |
clustered | false | BOOLEAN |
connection-ttl-override | -1 | LONG |
create-bindings-dir | true | BOOLEAN |
create-journal-dir | true | BOOLEAN |
failback-delay | 5000 | LONG |
failover-on-shutdown | false | BOOLEAN |
id-cache-size | 2000 | INT |
jmx-domain | org.hornetq | STRING |
jmx-management-enabled | false | BOOLEAN |
journal-buffer-size | 100 | LONG |
journal-buffer-timeout | 100 | LONG |
journal-compact-min-files | 10 | INT |
journal-compact-percentage | 30 | INT |
journal-file-size | 102400 | LONG |
journal-max-io | 1 | INT |
journal-min-files | 2 | INT |
journal-sync-non-transactional | true | BOOLEAN |
journal-sync-transactional | true | BOOLEAN |
journal-type | ASYNCIO | STRING |
live-connector-ref | reference | STRING |
log-journal-write-rate | false | BOOLEAN |
management-address | jms.queue.hornetq.management | STRING |
management-notification-address | hornetq.notifications | STRING |
memory-measure-interval | -1 | LONG |
memory-warning-threshold | 25 | INT |
message-counter-enabled | false | BOOLEAN |
message-counter-max-day-history | 10 | INT |
message-counter-sample-period | 10000 | LONG |
message-expiry-scan-period | 30000 | LONG |
message-expiry-thread-priority | 3 | INT |
page-max-concurrent-io | 5 | INT |
perf-blast-pages | -1 | INT |
persist-delivery-count-before-delivery | false | BOOLEAN |
persist-id-cache | true | BOOLEAN |
persistence-enabled | true | BOOLEAN |
remoting-interceptors | undefined | LIST |
run-sync-speed-test | false | BOOLEAN |
scheduled-thread-pool-max-size | 5 | INT |
security-domain | other | STRING |
security-enabled | true | BOOLEAN |
security-invalidation-interval | 10000 | LONG |
server-dump-interval | -1 | LONG |
shared-store | true | BOOLEAN |
started | true | BOOLEAN |
thread-pool-max-size | 30 | INT |
transaction-timeout | 300000 | LONG |
transaction-timeout-scan-period | 1000 | LONG |
version | 2.2.16.Final (HQ_2_2_16_FINAL, 122) | STRING |
wild-card-routing-enabled | true | BOOLEAN |
警告
journal-file-size
的值必须比发往服务器的消息大小要大,否则服务器无法存储这个消息。
第 10 章 Web、HTTP 连接器和 HTTP 群集
10.1. 配置 mod_cluster 工作节点
mod_cluster
子系统配置一次。要配置 mod_cluster
子系统,请参考《管理和配置指南》里的『配置 mod_cluster 子系统』。每个工作节点都是独立配置的,所以你可以为每个要加入群集的节点重复这个步骤。
工作节点配置
- 如果你使用了独立服务器,它必须以
standalone-ha
配置集启动。 - 如果你使用受管域,你的服务器组必须使用
ha
或full-ha
配置集,以及ha-sockets
或full-ha-sockets
套接字绑定组。JBoss EAP 附带满足这些要求的启用了群集的服务器组other-server-group
。
注意
/profile=full-ha
。
过程 10.1. 配置工作节点
配置网络接口。
在默认情况下,网络接口都是127.0.0.1
。每个容纳独立服务器或服务器组里的一个或多个服务器的物理主机的接口都需要进行配置以使用其他服务器可以看到的公共 IP 地址。要修改 JBoss EAP 主机的 IP 地址,你需要关闭它并直接修改配置文件。这是因为驱动管理控制台和管理 CLI 的 Management API 依赖于稳定的管理地址。遵循下列步骤将群集里的每个服务器的 IP 地址修改为主节点的公共 IP 地址。- 完全地关闭服务器。
- 对于受管域,编辑位于
EAP_HOME/domain/configuration/
里的host.xml
,而对于独立服务器,编辑位于EAP_HOME/standalone/configuration/
里的standalone-ha.xml
。 - 找到
<interfaces>
元素。有三个接口需要配置,management
、public
和unsecured
。你都要修改127.0.0.1
为主机的外部 IP 地址。 - 对于参与受管域但不是主节点的主机,找到
<host
元素。请注意,它没有结尾的>
符号,这是因为它包含了属性。将其 name 属性从master
修改为其他的唯一名称,每个从节点都应不同。这个名称也将被从节点用来标识群集,请注意这一点。 - 对于需要加入受管域的刚配置好的主机,找到
<domain-controller>
元素。注释或删除<local />
元素,并添加下列一行,修改 IP 地址(X.X.X.X
)为域控制台的地址。这个步骤不适用于独立服务器。<remote host="X.X.X.X" port="${jboss.domain.master.port:9999}" security-realm="ManagementRealm"/>
- 保存文件并退出。
为每个从服务器配置验证。
每个从服务器都需要在域控制器或独立主服务器的ManagementRealm
里创建一个用户名和密码。在域控制器或独立主服务器上,运行EAP_HOME/add-user.sh
命令。请用和从服务器相同的用户名添加一个用户到ManagementRealm
。当提示这个用户是否需要到外部的 JBoss AS 实例验证,请选择yes
。下面是这个命令的输入和输出的例子,从服务器名为slave1
,其密码为changeme
。user:bin user$ ./add-user.sh What type of user do you wish to add? a) Management User (mgmt-users.properties) b) Application User (application-users.properties) (a):
a
Enter the details of the new user to add. Realm (ManagementRealm) : Username :slave1
Password :changeme
Re-enter Password :changeme
About to add user 'slave1' for realm 'ManagementRealm' Is this correct yes/no?yes
Added user 'slave1' to file '/home/user/jboss-eap-6.0/standalone/configuration/mgmt-users.properties' Added user 'slave1' to file '/home/user/jboss-eap-6.0/domain/configuration/mgmt-users.properties' Is this new user going to be used for one AS process to connect to another AS process e.g. slave domain controller? yes/no? yes To represent the user add the following to the server-identities definition <secret value="Y2hhbmdlbWU=" />从
add-user.sh
的输出里复制 Base64 编码的<secret>
元素。如果你计划验证时指定 Base64 编码的密码,请复制add-user.sh
的输出里的<secret>
元素值,你在下面的步骤里需要用到它。修改从主机的安全区以使用新的验证。
- 重新打开从主机的
host.xml
或standalone-ha.xml
文件。 - 找到
<security-realms>
元素。这是你配置安全区(Security Realm)的地方。 - 你可以用下列方法之一指定 secret 值:
在配置文件里指定 Base64 编码的密码值。
- 在
<security-realm name="ManagementRealm">
行下添加下列 XML 片段:<server-identities> <secret value="Y2hhbmdlbWU="/> </server-identities>
- 用前一步骤的
add-user.sh
输出里返回的 secret 值来替换 "Y2hhbmdlbWU=" 。
配置主机通过 vault.sh 获取密码。
- 使用
vault.sh
脚本生成一个加密的密码。它将生成一个这样的字符串:VAULT::secret::password::ODVmYmJjNGMtZDU2ZC00YmNlLWE4ODMtZjQ1NWNmNDU4ZDc1TElORV9CUkVBS3ZhdWx0
。你可以在本指南的『敏感字符串的密码阀』里找到更多信息:第 3.8.1 节 “关于保护明码文件里的敏感字符”。 - 在
<security-realm name="ManagementRealm">
行下添加下列 XML 片段:<server-identities> <secret value="${VAULT::secret::password::ODVmYmJjNGMtZDU2ZC00YmNlLWE4ODMtZjQ1NWNmNDU4ZDc1TElORV9CUkVBS3ZhdWx0}"/> </server-identities>
请用前一步骤生成的加密密码替换 secret 值。注意
当在阀里创建一个密码时,它必须以明文而不是 Base64 编码来指定。
指定密码为系统属性。
- 在
<security-realm name="ManagementRealm">
行下直接添加下列 XML 代码块。<server-identities> <secret value=${server.identity.password}/> </server-identities>
- 当你将密码指定为系统属性时,你可以用下列方法之一配置主机:
- 在命令行里以明文输入密码来启动服务器,例如:
-Dserver.identity.password=changeme
注意
密码必须以明文输入并对于任何执行ps -ef
命令的用户可见。 - 将密码放在属性文件里并将文件的 URL 作为命令行参数传入。
- 在属性文件里添加键/值对。例如:
server.identity.password=changeme
- 用命令行参数启动服务器:
--properties=URL_TO_PROPERTIES_FILE
.
- 保存文件并退出。
重启服务器。
从主机现在将以主机名为用户名以及加密的字符串为密码来向主服务器进行验证。
第 11 章 网络安全性
11.1. 保护管理接口
在测试环境里,我们通常在由管理控制台、管理 CLI 和其他 API 实现组成的管理接口上不设置安全层来运行 JBoss EAP 6 。这可以允许快速的开发和配置修改。
11.2. 指定 JBoss EAP 使用的网络接口
隔离服务以使它们只被需要它们的客户访问,这样可以增强网络的安全性。JBoss EAP 在其默认配置里包含两个接口,两者都绑定到 IP 地址127.0.0.1
或 localhost
。其中一个被称为 management
,它被管理控制台、CLI 和 API 使用。另外一个被称为 public
,被用来部署应用程序。这些接口并不特殊或有什么含义,只是作为起点来提供。
management
接口默认使用端口 9990 和 9999,而public
接口使用端口 8080 或 8443(如果使用 HTTPS)。
警告
停止 JBoss EAP。
以合适的方式对操作系统发送中断信号来停止 JBoss EAP。如果你以前台应用程序的方式运行 JBoss EAP ,那通常的做法是按 Ctrl+C 键。重启 JBoss EAP,指定绑定地址。
使用-b
命令行选项在特定接口上启动 JBoss EAP。例 11.1. 指定公共接口。
EAP_HOME/bin/domain.sh -b 10.1.1.1
例 11.2. 指定管理接口。
EAP_HOME/bin/domain.sh -bmanagement=10.1.1.1
例 11.3. 为每个接口指定不同的地址。
EAP_HOME/bin/domain.sh -bmanagement=127.0.0.1 -b 10.1.1.1
例 11.4. 绑定公共接口到所有的网络接口上。
EAP_HOME/bin/domain.sh -b 0.0.0.0
-b
命令行选项在运行时指定 IP 地址,所以我们不推荐这么做。如果确实要这么做,请在编辑 XML 文件前完全停止 JBoss EAP。
11.3. 配置和 JBoss EAP 6 一起使用的网络防火墙
多数产品环境都使用防火墙作为总体网络安全策略的一部分。如果你需要多个 EAP 服务器来与其他 EAP 服务器或外部服务(如 Web 服务器或数据库)来通讯,你的防火墙需要考虑这一点。管理良好的防火墙只会打开操作所需的端口,它会限制对某些 IP 地址、子网和网络协议的端口的访问。
前提条件
- 确定你要打开的端口。请参考 第 11.4 节 “JBoss EAP 6使用的网络端口” 以确定端口列表。
- 对防火墙软件的理解是必需的。在红帽企业版 Linux 6 里,这个过程会使用
system-config-firewall
命令。微软的 Windows 服务器包括了内置的防火墙,以及几个可用于任何平台的第三方的防火墙解决方案。
这个过程配置防火墙是基于如下假设的:
- 操作系统为红帽企业版 Linux 6。
- EAP 运行在主机
10.1.1.2
上。或者,EAP 服务器具有自己的防火墙。 - 网络防火墙服务器运行在主机
10.1.1.1
的接口eth0
上,且具有外部的接口eth1
。 - 你想把端口 5445(JMS 使用的端口)上的流量转发到 JBoss EAP 6。网络防火墙应该不允许其他流量通过。
过程 11.1. 管理和 JBoss EAP 6 一起使用的网络防火墙
登录到管理控制台。
登录到管理控制台。在默认情况下,它运行在 http://localhost:9990/console/ 上。确定套接字绑定组使用的套接字绑定。
点击管理控制台右上方的 Profiles 标签。在屏幕的左侧会显示一系列菜单。菜单底部是 General Configuration。点击 Socket Binding Groups。Socket Binding Declarations 屏幕将会出现。你可以从右侧的复合框里来选择不同的组。注意
如果你使用的是独立服务器,它只有一个套接字绑定组。套接字名称和端口将会出现,每页有 6 个值。你可以使用表下面的箭头来进行浏览。确定你要打开的端口。
根据特定端口的功能以及环境的需要,一些端口可能需要通过防火墙来访问。如果你不确定某个套接字绑定的目的,请参考 第 11.4 节 “JBoss EAP 6使用的网络端口” 里关于默认套接字绑定和其目的的列表。配置防火墙将通讯转发到 JBoss EAP 6。
执行这些步骤来配置网络防火墙以允许指定端口上的通讯。- 登录到防火墙主机并以根用户身份打开命令行提示。
- 执行
system-config-firewall
来启动防火墙配置工具。GUI 或命令行工具根据你登录到防火墙系统的方式启动。这个任务假设你通过 SSH 登录并使用了命令行接口。 - 使用 TAB 键切换到 Trusted Services 屏幕将会出现。按钮,然后按 ENTER 键。
- 不要修改任何值,使用 TAB 键切换到 Other Ports 屏幕将出现。按钮,然后按 ENTER 键进入下一屏幕。
- 使用 TAB 键切换到 Port and Protocol 屏幕将会出现。按钮,然后按 ENTER 键。
- 在 Port / Port Range 字段里输入
5445
,然后使用 TAB 键切换到 Protocol 字段,并输入tcp
。使用 TAB 键切换到 按钮,然后按 ENTER 键。 - 使用 TAB 键切换到 Port Forwarding 屏幕。按钮,直至你到达
- 使用 TAB 键切换到按钮,然后按 ENTER 键。
- 填写下列值以设立端口映射到 5445。
- 源接口:eth1
- 协议:tcp
- 端口 / 端口范围:5445
- 目的 IP 地址:10.1.1.2
- 端口 / 端口范围:5445
使用 TAB 键切换到按钮,然后按 ENTER。 - 使用 TAB 键切换到按钮,然后按 ENTER。
- 使用 TAB 键切换到按钮,然后按 ENTER。要应用这些改动,阅读警告提示并点击 。
在你的 JBoss EAP 6 主机上配置防火墙。
一些机构选择在 JBoss EAP 6 服务器上配置防火墙,并关闭非操作必需的端口。请参考 第 11.4 节 “JBoss EAP 6使用的网络端口” 并确定要打开的端口,然后关闭其他端口。红帽企业版 6 的默认配置关闭所有的端口,除了 22(用于 SSH)和 5253(用于多点传送 DNS)。当你在配置端口的时候,请确保你可以从物理上访问服务器,这样就不会不经意地锁住自己。
配置了防火墙,它会按照你在防火墙配置里指定的将通讯转发到内部的 JBoss EAP 6 服务器。如果你选择在 EAP 服务器上启用防火墙,除了需要运行应用程序的端口,所有的端口将被关闭。
11.4. JBoss EAP 6使用的网络端口
- 你的服务器组是否使用了默认的套接字绑定组,或者自定义的套接字绑定组。
- 单独部署的要求。
注意
默认的套接字绑定组
full-ha-sockets
full-sockets
ha-sockets
standard-sockets
名称 | 端口 | 多点传送端口 | 描述 | full-ha-sockets | full-sockets | ha-socket | standard-socket |
---|---|---|---|---|---|---|---|
ajp | 8009 | Apache JServ 协议,用于 HTTP 群集和负载平衡。 | 是 | 是 | 是 | 是 | |
http | 8080 | 用于已部署应用程序的默认端口。 | 是 | 是 | 是 | 是 | |
https | 8443 | 已部署的应用程序和客户间的用 SSL 加密的连接。 | 是 | 是 | 是 | 是 | |
jacorb | 3528 | 用于 JTS 事务的 CORBA 服务和其他依赖于 ORB 的服务。 | 是 | 是 | 否 | 否 | |
jacorb-ssl | 3529 | SSL 加密的 CORBA 服务。 | 是 | 是 | 否 | 否 | |
jgroups-diagnostics | 7500 | 多点传送。用于 HA 群集里的 Peer 发现。 | 是 | 否 | 是 | 否 | |
jgroups-mping | 45700 | 多点传送。用于在 HA 群集里发现初始成员资格。 | 是 | 否 | 是 | 否 | |
jgroups-tcp | 7600 | HA 群集里使用 TCP 的多点传送 Peer 发现。 | 是 | 否 | 是 | 否 | |
jgroups-tcp-fd | 57600 | 用于 TCP 上的 HA 失败检测。 | 是 | 否 | 是 | 否 | |
jgroups-udp | 55200 | 45688 | HA 群集里使用 UDP 的多点传送 Peer 发现。 | 是 | 否 | 是 | 否 |
jgroups-udp-fd | 54200 | 用于 UDP 上的 HA 失败检测。 | 是 | 否 | 是 | 否 | |
messaging | 5445 | JMS 服务。 | 是 | 是 | 否 | 否 | |
messaging-group | 被 HornetQ JMS 广播和发现组引用。 | 是 | 是 | 否 | 否 | ||
messaging-throughput | 5455 | JMS remoting 所使用的。 | 是 | 是 | 否 | 否 | |
mod_cluster | 23364 | 用于 JBoss EAP 和 HTTP 加载平衡器之间通讯的多点传送端口。 | 是 | 否 | 是 | 否 | |
osgi-http | 8090 | 由使用 OSGi 子系统的内部组件使用。 | 是 | 是 | 是 | 是 | |
remoting | 4447 | 用于远程 EJB 调用。 | 是 | 是 | 是 | 是 | |
txn-recovery-environment | 4712 | JTA 事务恢复管理者。 | 是 | 是 | 是 | 是 | |
txn-status-manager | 4713 | JTA / JTS 事务管理者。 | 是 | 是 | 是 | 是 |
除了套接字绑定组,每个主机控制台都打开另外两个端口用于管理:
- 9990 - Web 管理控制台的端口
- 9999 - 管理控制台和 API 使用的端口
部分 III. 保证应用程序的安全
第 12 章 应用程序的安全性
12.1. 启用/禁用基于描述符的属性替换
警告
12.2. 数据源安全性
12.2.1. 关于数据源安全性
- 安全域:第 6.1 节 “关于安全域”。
例 12.1. 安全域示例
<security> <security-domain>mySecurityDomain</security-domain> </security>
例 12.2. 密码阀示例
<security> <user-name>admin</user-name> <password>${VAULT::ds_ExampleDS::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0}</password> </security>
12.3. EJB 应用程序的安全性
12.3.1. 安全标识符
12.3.1.1. 关于 EJB 的安全标识符
<security-identity>
标记。它表示其他 EJB 在调用组件上的方法时必须使用的标识符。
<use-caller-identity>
标签,而第二种情况则使用 <run-as>
标签。
12.3.1.2. 设置 EJB 的安全标识符
例 12.3. 设置 EJB 和其调用者相同的安全标识符
<security-identity>
元素声明,这个行为是默认的。
<ejb-jar> <enterprise-beans> <session> <ejb-name>ASessionBean</ejb-name> <!-- ... --> <security-identity> <use-caller-identity/> </security-identity> </session> <!-- ... --> </enterprise-beans> </ejb-jar>
例 12.4. 设置 EJB 的安全标识符为特定的角色
<security-identity>
标签里的 <run-as>
或 <role>
标签。
<ejb-jar> <enterprise-beans> <session> <ejb-name>RunAsBean</ejb-name> <!-- ... --> <security-identity> <run-as> <description>A private internal role</description> <role-name>InternalRole</role-name> </run-as> </security-identity> </session> </enterprise-beans> <!-- ... --> </ejb-jar>
<run-as>
时,名为 anonymous
的 principal 被分配给转出调用。要分配不同的 principal,请使用 <run-as-principal>
。
<session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as-principal>internal</run-as-principal> </security-identity> </session>
注意
<run-as>
和 <run-as-principal>
元素。
12.3.2. EJB 方法权限
12.3.2.1. 关于 EJB 方法权限(EJB Method Permission)
<method-permisison>
元素声明。这个声明设置了被允许调用 EJB 的接口方法的角色。你可以为下列组合指定权限:
- 命名 EJB 的所有 home 和 component 接口方法
- 命名 EJB 的 home 或 component 接口的一个指定的方法
- 具有重载名的一系列方法里的一个指定的方法
12.3.2.2. 使用 EJB Method Permission
<method-permission>
元素定义了被允许访问 <method>
定义的 EJB 方法的逻辑角色。下面的几个例子演示了 XML 的语法。其中多个 method permission 语句可能会出现并具有累积的效应。<method-permission>
元素是 <ejb-jar>
描述符里 <assembly-descriptor>
元素的一个子元素。
例 12.5. 允许角色访问 EJB 的所有方法:
<method-permission> <description>The employee and temp-employee roles may access any method of the EmployeeService bean </description> <role-name>employee</role-name> <role-name>temp-employee</role-name> <method> <ejb-name>EmployeeService</ejb-name> <method-name>*</method-name> </method> </method-permission>
例 12.6. 允许角色访问 EJB 的某个方法,并限制可以传递哪些方法参数:
<method-permission> <description>The employee role may access the findByPrimaryKey, getEmployeeInfo, and the updateEmployeeInfo(String) method of the AcmekPayroll bean </description> <role-name>employee</role-name> <method> <ejb-name>AcmekPayroll</ejb-name> <method-name>findByPrimaryKey</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>getEmployeeInfo</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>updateEmployeeInfo</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </method-permission>
例 12.7. 允许经验证的用户访问 EJB 的方法
<unchecked/>
元素可以允许任何经验证的用户使用指定的方法。
<method-permission> <description>Any authenticated user may access any method of the EmployeeServiceHelp bean</description> <unchecked/> <method> <ejb-name>EmployeeServiceHelp</ejb-name> <method-name>*</method-name> </method> </method-permission>
例 12.8. 完全排除使用特定的 EJB 方法:
<exclude-list> <description>No fireTheCTO methods of the EmployeeFiring bean may be used in this deployment</description> <method> <ejb-name>EmployeeFiring</ejb-name> <method-name>fireTheCTO</method-name> </method> </exclude-list>
例 12.9. 包含几个 <method-permission>
块的完整 <assembly-descriptor>
例子:
<ejb-jar> <assembly-descriptor> <method-permission> <description>The employee and temp-employee roles may access any method of the EmployeeService bean </description> <role-name>employee</role-name> <role-name>temp-employee</role-name> <method> <ejb-name>EmployeeService</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <description>The employee role may access the findByPrimaryKey, getEmployeeInfo, and the updateEmployeeInfo(String) method of the AcmePayroll bean </description> <role-name>employee</role-name> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>findByPrimaryKey</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>getEmployeeInfo</method-name> </method> <method> <ejb-name>AcmePayroll</ejb-name> <method-name>updateEmployeeInfo</method-name> <method-params> <method-param>java.lang.String</method-param> </method-params> </method> </method-permission> <method-permission> <description>The admin role may access any method of the EmployeeServiceAdmin bean </description> <role-name>admin</role-name> <method> <ejb-name>EmployeeServiceAdmin</ejb-name> <method-name>*</method-name> </method> </method-permission> <method-permission> <description>Any authenticated user may access any method of the EmployeeServiceHelp bean</description> <unchecked/> <method> <ejb-name>EmployeeServiceHelp</ejb-name> <method-name>*</method-name> </method> </method-permission> <exclude-list> <description>No fireTheCTO methods of the EmployeeFiring bean may be used in this deployment</description> <method> <ejb-name>EmployeeFiring</ejb-name> <method-name>fireTheCTO</method-name> </method> </exclude-list> </assembly-descriptor> </ejb-jar>
12.3.3. EJB 安全注解
12.3.3.1. 关于 EJB 安全注解
- @DeclareRoles
- 声明哪些角色是可用的。
- @SecurityDomain
- 指定用于 EJB 的安全域。如果 EJB 的授权用
@RolesAllowed
进行注解,授权将只在 EJB 用安全域注解时才会应用。 - @RolesAllowed, @PermitAll, @DenyAll
- 指定哪些方法权限是被允许的。关于方法权限的更多信息,请参考 第 12.3.2.1 节 “关于 EJB 方法权限(EJB Method Permission)”。
- @RolesAllowed, @PermitAll, @DenyAll
- 指定哪些方法权限是被允许的。关于方法权限的更多信息,请参考 第 12.3.2.1 节 “关于 EJB 方法权限(EJB Method Permission)”。
- @RunAs
- 配置组件的传播的安全标识符。
12.3.3.2. 使用 EJB 安全注解
你可以使用 XML 描述符或注解来控制哪些安全角色能够调用你的 EJB 里的方法。关于使用 XML 描述符的更多信息,请参考 第 12.3.2.2 节 “使用 EJB Method Permission”。
控制 EJB 的安全权限的注解
- @DeclareRoles
- 使用 @DeclareRoles 来定义针对哪些安全角色检查权限。如果没有使用 @DeclareRoles,这个列表将自动根据 @RolesAllowed 注解进行构建。
- @SecurityDomain
- 指定用于 EJB 的安全域。如果 EJB 的授权用
@RolesAllowed
进行注解,授权将只在 EJB 用安全域注解时才会应用。 - @RolesAllowed, @PermitAll, @DenyAll
- 使用 @RolesAllowed 来列出哪些角色别允许访问某个或某些方法。使用 @PermitAll 或 @DenyAll 来允许或拒绝所有的角色使用某个或某些方法。
- @RunAs
- 使用 @RunAs 来指定总是以之运行的某个角色或方法。
例 12.10. 安全性注解示例
@Stateless @RolesAllowed({"admin"}) @SecurityDomain("other") public class WelcomeEJB implements Welcome { @PermitAll public String WelcomeEveryone(String msg) { return "Welcome to " + msg; } @RunAs("tempemployee") public String GoodBye(String msg) { return "Goodbye, " + msg; } public String public String GoodbyeAdmin(String msg) { return "See you later, " + msg; } }
WelcomeEveryone
。 GoodBye
方法以 tempemployee
角色运行。只有 admin
角色可以访问方法 GoodbyeAdmin
,以及其他任何没有使用安全性注解的的方法。
12.3.4. 对 EJB 的远程访问
12.3.4.1. 关于远程方法访问
支持的传输类型
- Socket / Secure Socket
- RMI / RMI over SSL
- HTTP / HTTPS
- Servlet / Secure Servlet
- Bisocket / Secure Bisocket
Remoting 系统也提供数据编码(Data Marshalling)和解码(Unmarshalling)服务。数据编码指的是在网络间和平台边界安全移动数据的能力,这样独立的系统就可以在上面执行任务。然后这个任务被送回原来的系统,就像是在本地处理的一样。
当你设计一个使用 Remoting 的客户应用程序时,通过配置它使用特定的资源定位器 InvokerLocator
(它是一个 URL 类型格式的简单 String 对象),你可以指引应用程序和服务器通讯。服务器侦听作为 remoting
子系统的一部分配置的 connector
上的远程资源的请求 。connector
将请求传给配置好的 ServerInvocationHandler
。每个 ServerInvocationHandler
都实现了一个 invoke(InvocationRequest)
方法,它知道如何处理这个请求。
JBoss Remoting 框架层次
- 用户和 outer 层交互。在客户端,outer 层是
Client
类,它发送调用请求。在服务器端,它是 InvocationHandler,由用户实现并接收调用请求。 - 传输是由调用层控制的。
- 最底层包含 mashaller 和 unmashaller,它们将 mats 数据转换为线格式(Wire Format)。
12.3.4.2. 关于远程回调
InvocationRequest
给客户端。服务器端的代码与之相同而不管回调是异步还是同步的。只有客户需要知道这个区别。服务器的 InvocationRequest 发送一个 responseObject
给客户端。这是客户端已经请求的负载。这可以是一个对请求的直接响应或事件通知。
m_listeners
来追踪侦听器。它包含一个已添加至你的服务器处理程序里的侦听器列表。ServerInvocationHandler
接口包含允许你管理这个列表的方法。
org.jboss.remoting.InvokerCallbackHandler
接口的实现,它处理回调数据。在实现了回调处理器后,你可以将自己添加为 pull 回调的侦听器,或者实现一个回调服务器来处理 push 回调。
对于 pull 回调,你的客户端通过 Client.addListener()
方法将自己添加到服务器的侦听器列表里。然后,它定期轮询服务器的同步回调数据递送。轮询是通过 Client.getCallbacks()
进行的。
Push 回调要求你的客户端应用程序运行自己的 InvocationHandler。为此,你需要在客户端运行一个 Remoting 服务。这被称为回调服务器(Callback Server)。回调服务器异步接受转入请求并为请求者(这个例子里是服务器)处理它们。要在主服务器里注册你的客户的回调服务器,请将回调服务器的 InvokerLocator
作为第二个参数传入 addListener
方法。
12.3.4.3. 关于远程服务器检测
12.3.4.4. 配置 Remoting 子系统
JBoss Remoting 有三个顶层的可配置元素:工作者线程池、一个或多个连接器以及一系列本地和远程的连接 URL。本主题解释了每个可配置条目、配置这些条目的示例 CLI 命令,以及一个完整配置子系统的 XML 示例。这个配置只适用于服务器。多数情况下都根本不需要配置 Remoting 子系统,除非你使用了自定义的连接器。作为 Remoting 客户的应用程序,如 EJB,都需要单独的配置来连接专有的连接器。
注意
当配置 default
配置集时,CLI 命令格式是对应受管域的。如要配置不同的配置集,请替换它的名称。对于独立服务器,请忽略命令里的 /profile=default
部分。
Remoting
子系统外部的一些配置是:
- 网络接口
Remoting
子系统使用的网络接口是domain/configuration/domain.xml
或standalone/configuration/standalone.xml
里定义的unsecure
接口。<interfaces> <interface name="management"/> <interface name="public"/> <interface name="unsecure"/> </interfaces>
unsecure
接口的 per-host 定义是在和domain.xml
或standalone.xml
相同目录里的host.xml
里定义的。其他几个子系统也使用了这个接口。修改它时请小心。<interfaces> <interface name="management"> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> </interface> <interface name="public"> <inet-address value="${jboss.bind.address:127.0.0.1}"/> </interface> <interface name="unsecure"> <!-- Used for IIOP sockets in the standard configuration. To secure JacORB you need to setup SSL --> <inet-address value="${jboss.bind.address.unsecure:127.0.0.1}"/> </interface> </interfaces>
- socket-binding
remoting
使用的默认 socket-binding 绑定在 TCP 端口 4777。如果你要修改它,请参阅文档以获得关于套接字绑定和套接字绑定组的更多信息。- EJB 的 Remoting 连接器引用
- EJB 子系统包含对 remoting 连接器的引用以用于远程方法调用。下面是默认的配置:
<remote connector-ref="remoting-connector" thread-pool-name="default"/>
- 安全传输配置
- 在客户请求安全连接时,Remoting 传输使用 StartTLS 来使用 HTTPS、Secure Servlet 等。安全和非安全的连接都使用相同的套接字绑定(网络端口),所以不需要额外的服务器端配置。客户按照需要请求安全或非安全传输时。使用 Remoting 的 JBoss 企业级应用程序平台组件,如 EJB、ORB、JMS 提供者,在默认情况下都使用安全的接口。
警告
工作者线程池是处理来自 Remoting 连接器的任务的线程组。它是一个单一的元素 <worker-thread-pool>
,并使用几个属性。如果你遇到网络超时、线程用尽或需要限制内存使用,你可以调整这些属性。其推荐值取决于特定的环境。更多的信息,请联系红帽全球支持服务。
属性 | 描述 | CLI 命令 |
---|---|---|
read-threads |
为远程 worker 创建的读线程数目。默认为
1 。
| /profile=default/subsystem=remoting/:write-attribute(name=worker-read-threads,value=1)
|
write-threads |
为远程 worker 创建的写线程数目。默认为
1 。
| /profile=default/subsystem=remoting/:write-attribute(name=worker-write-threads,value=1)
|
task-keepalive |
非核心 remoting worker 任务保持活动状态所需的毫秒数。默认为
60 。
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-keepalive,value=60)
|
task-max-threads |
用于 remoting worker 任务线程池的线程的个数。默认为
16 。
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-max-threads,value=16)
|
task-core-threads |
用于 remoting worker 任务线程池的内核个数。默认为
4 。
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-core-threads,value=4)
|
task-limit |
在拒绝前允许的 remoting worker 任务的最大个数。默认为
16384 。
| /profile=default/subsystem=remoting/:write-attribute(name=worker-task-limit,value=16384)
|
连接器是主要的远程配置元素。可以存在多个连接器。每个都由一个 <connector>
元素、几个子元素以及一些属性组成。默认的连接器由几个 JBoss EAP 的子系统使用。对自定义连接器的元素和属性的设置取决于你的应用程序,更多的信息请联系红帽全球支持服务。
属性 | 描述 | CLI 命令 |
---|---|---|
name | JNDI 使用的连接器的名称。 | /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=name,value=remoting-connector)
|
socket-binding | 这个连接器使用的套接字绑定的名称。 | /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=socket-binding,value=remoting)
|
authentication-provider |
和这个连接器一起使用的 Java Authentication Service Provider Interface for Containers (JASPIC)。这个模块必须位于 classpath 里。
| /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=authentication-provider,value=myProvider)
|
security-realm |
可选的。包含应用程序的用户、密码和角色的安全区。EJB 或 Web 应用程序可以针对安全区进行验证。默认的 JBoss 企业级应用程序平台安装里
ApplicationRealm 是可用的。
| /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=security-realm,value=ApplicationRealm)
|
属性 | 描述 | CLI 命令 |
---|---|---|
sasl |
用于简单验证和安全层(Simple Authentication and Security Layer,SASL)验证机制的封装元素
| N/A
|
properties |
包含一个或多个
<property> 元素,每个都带有一个 name 属性和一个可选的 value 属性。
| /profile=default/subsystem=remoting/connector=remoting-connector/property=myProp/:add(value=myPropValue)
|
你可以指定三种不同类型的转出连接:
- 到 URI 的转出连接。
- 本地的转出连接 – 连接至本地资源,如套接字。
- 远程转出连接 – 连接至远程资源并使用安全区进行验证。
<outbound-connections>
元素里。这些连接类型都使用了一个 outbound-socket-binding-ref
属性。outbound-connection 使用了一个 uri
属性。远程的转出连接使用可选的 username
和 security-realm
属性以用于授权。
属性 | 描述 | CLI 命令 |
---|---|---|
outbound-connection | 普通的转出连接。 | /profile=default/subsystem=remoting/outbound-connection=my-connection/:add(uri=http://my-connection)
|
local-outbound-connection | 带有隐含的 local:// URI 模式的转出连接。 | /profile=default/subsystem=remoting/local-outbound-connection=my-connection/:add(outbound-socket-binding-ref=remoting2)
|
remote-outbound-connection |
用于 remote:// URI 模式的转出连接,它使用安全区的 basic/digest 验证。
| /profile=default/subsystem=remoting/remote-outbound-connection=my-connection/:add(outbound-socket-binding-ref=remoting,username=myUser,security-realm=ApplicationRealm)
|
在定义每个 SASL 子元素之前,你需要创建初始的 SASL 元素。请使用下列命令:
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:add
属性 | 描述 | CLI 命令 |
---|---|---|
include-mechanisms |
包含一个
value 属性,它是一个以空格隔开的 SASL 机制的列表。
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=include-mechanisms,value=["DIGEST","PLAIN","GSSAPI"]) |
qop |
包含一个
value 属性,它是一个以空格隔开的 SASL Quality of Protection 值的列表,以降序排列。
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=qop,value=["auth"]) |
strength |
包含一个
value 属性,它是一个以空格隔开的 SASL 计算强度值的列表,以降序排列。
|
/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=strength,value=["medium"]) |
reuse-session |
包含一个布尔值的
value 属性。如果为 true,它将试图重用会话。
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=reuse-session,value=false) |
server-auth |
包含一个布尔值的
value 属性。如果为 true,服务器将验证客户。
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl:write-attribute(name=server-auth,value=false) |
policy |
包含零或多个下列元素的封装元素,其中每个元素都使用单个的
value 。
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:add /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=forward-secrecy,value=true) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-active,value=false) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-dictionary,value=true) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=no-plain-text,value=false) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/sasl-policy=policy:write-attribute(name=pass-credentials,value=true) |
properties |
包含一个或多个
<property> 元素,每个都带有一个 name 属性和一个可选的 value 属性。
|
/profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/property=myprop:add(value=1) /profile=default/subsystem=remoting/connector=remoting-connector/security=sasl/property=myprop2:add(value=2) |
例 12.11. 配置示例
<subsystem xmlns="urn:jboss:domain:remoting:1.1"> <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/> </subsystem>
<subsystem xmlns="urn:jboss:domain:remoting:1.1"> <worker-thread-pool read-threads="1" task-keepalive="60' task-max-threads="16" task-core-thread="4" task-limit="16384" write-threads="1" /> <connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"> <sasl> <include-mechanisms value="GSSAPI PLAIN DIGEST-MD5" /> <qop value="auth" /> <strength value="medium" /> <reuse-session value="false" /> <server-auth value="false" /> <policy> <forward-secrecy value="true" /> <no-active value="false" /> <no-anonymous value="false" /> <no-dictionary value="true" /> <no-plain-text value="false" /> <pass-credentials value="true" /> </policy> <properties> <property name="myprop1" value="1" /> <property name="myprop2" value="2" /> </properties> </sasl> <authentication-provider name="myprovider" /> <properties> <property name="myprop3" value="propValue" /> </properties> </connector> <outbound-connections> <outbound-connection name="my-outbound-connection" uri="htt\ p://myhost:7777/"/> <remote-outbound-connection name="my-remote-connection" outbound-socket-binding-ref="my-remote-socket" username="myUser" security-realm="ApplicationRealm"/> <local-outbound-connection name="myLocalConnection" outbound-socket-binding-ref="my-outbound-socket"/> </outbound-connections> </subsystem>
Configuration Aspects Not Yet Documented
- JNDI 和多点传送的自动检测
12.3.4.5. 对远程 EJB 客户使用安全区
- 添加新的安全区到域控制器或独立服务器里。
- 添加下列参数到位于应用程序的 classpath 上的
jboss-ejb-client.properties
文件里。这个例子假设文件里的其他参数引用的连接是default
。remote.connection.default.username=appuser remote.connection.default.password=apppassword
- 在域或独立服务器上创建一个使用新的安全区的自定义远程连接器。
- 部署 EJB 到使用带有自定义远程连接器的服务器组里,如果你使用的不是受管域则部署到独立服务器里。
12.3.4.6. 添加新的安全区
运行管理 CLI。
运行jboss-cli.sh
或jboss-cli.bat
命令并连接服务器。创建新的安全区。
运行下列命令在域控制器或独立服务器上创建一个名为MyDomain
的安全区。/host=master/core-service=management/security-realm=MyDomainRealm:add()
创建对将保存新角色信息的属性文件的引用。
运行下列命令创建一个名为myfile.properties
的文件,它将包含附属新角色的属性。注意
新创建的属性文件不是由内含的add-user.sh
和add-user.bat
脚本管理的。它必须进行外部管理。/host=master/core-service=management/security-realm=MyDomainRealm/authentication=properties:add(path=myfile.properties)
你的新安全区已被创建了。当你添加用户和角色到这个新的安全区时,信息将被存储在默认安全区外的一个单独的文件里。你可以用自己的应用程序或过程来管理这个新的文件。
12.3.4.7. 添加用户到安全区里
运行
add-user.sh
或add-user.bat
命令。打开一个命令行界面(command-line interface,CLI)。进入EAP_HOME/bin/
目录。如果你运行的是红帽企业版 LInux 或其他类 Unix 系统,请运行add-user.sh
。如果你运行的是 Microsoft Windows 服务器,则请运行add-user.bat
。选择是否添加管理用户或应用程序用户。
对于这个过程,输入b
来添加应用程序用户。选择用户所添加至的安全区。
在默认的情况下,唯一可用的安全区是ApplicationRealm
。如果你已经添加了一个自定义区,你可以输入它的名称。在提示时输入用户名、密码和角色。
在提示时输入想要的用户名、密码和可选角色。输入yes
确认选择或no
取消修改。所作修改将被写入到安全区的每个属性文件里。
12.3.4.8. 关于使用 SLL 加密的远程 EJB 访问
12.4. JAX-RS 应用程序的安全性
12.4.1. 为 RESTEasy JAX-RS Web 服务启用基于角色的安全性
RESTEasy 支持 JAX-RS 方法上的 @RolesAllowed、@PermitAll 和 @DenyAll 注解。然而,在默认情况下它并不承认这些注解。请遵循这些步骤来配置 web.xml
文件并启用基于角色的安全性。
警告
过程 12.1. 为 RESTEasy JAX-RS Web 服务启用基于角色的安全性
- 在文本编辑器里打开应用程序的
web.xml
文件。 - 添加下列 <context-param> 到文件的
web-app
标签下:<context-param> <param-name>resteasy.role.based.security</param-name> <param-value>true</param-value> </context-param>
- 使用 <security-role> 标签声明在 RESTEasy JAX-RS WAR 文件里使用的角色:
<security-role><role-name>ROLE_NAME</role-name></security-role><security-role><role-name>ROLE_NAME</role-name></security-role>
- 为所有角色授权对 JAX-RS 运行时处理的所有 URL 的访问:
<security-constraint><web-resource-collection><web-resource-name>Resteasy</web-resource-name><url-pattern>/PATH</url-pattern></web-resource-collection><auth-constraint><role-name>ROLE_NAME</role-name><role-name>ROLE_NAME</role-name></auth-constraint></security-constraint>
这个应用程序里已经启用了基于角色的安全性并定义了一系列角色。
例 12.12. 基于角色的安全性配置示例
<web-app> <context-param> <param-name>resteasy.role.based.security</param-name> <param-value>true</param-value> </context-param> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection> <web-resource-name>Resteasy</web-resource-name> <url-pattern>/security</url-pattern> </web-resource-collection> <auth-constraint> <role-name>admin</role-name> <role-name>user</role-name> </auth-constraint> </security-constraint> <security-role> <role-name>admin</role-name> </security-role> <security-role> <role-name>user</role-name> </security-role> </web-app>
12.4.2. 使用注解保护 JAX-RS Web 服务
这个主题涵盖了使用支持的安全注解来保护 JAX-RS Web 服务的安全。
过程 12.2. 使用支持的安全注解保护 JAX-RS Web 服务
- 启用基于角色的安全性。更多信息请参考:第 12.4.1 节 “为 RESTEasy JAX-RS Web 服务启用基于角色的安全性”。
- 添加安全注解到 JAX-RS Web 服务里。RESTEasy 支持下列注解:
- @RolesAllowed
- 定义哪个角色可以访问这个方法。所有的角色都应该在
web.xml
文件里定义。 - @PermitAll
- 允许
web.xml
文件里定义的所有角色访问这个方法。 - @DenyAll
- 拒绝所有对这个方法的访问。
12.5. 安全远程密码协议
12.5.1. 关于安全远程密码协议
这个文档描述了一个强加密的的网络验证机制:安全远程密码(Secure Remote Password,SRP)协议。这个机制适合于使用用户提供的密码来协商安全连接,从而消除传统的和可重用密码相关联的安全问题。这个系统在验证过程中也执行一个安全密钥的交换,允许在会话过程中启用安全层(隐私和/或完整性保护)。这不要求信任的密钥服务器和证书基础结构,也不要求存储或管理任何长期的密钥。对比现有的挑战应答(challenge-response)技术,SRP 有安全性和部署的优势,在需要安全密码验证的时候是一个理想的替代方案。
12.5.2. 配置安全远程密码协议
SRPVerifierStore
接口的 MBean。关于这个实现的信息位于 SRPVerifierStore 实现。
过程 12.3. 集成现有的密码库
创建 hashed 密码信息库。
如果密码已经以不可逆的 hashed 形式存储,对每个用户你都需要这么做。你可以实现setUserVerifier(String, VerifierInfo)
为 noOp 方法,或者抛出表示这个库是只读的异常。创建 SRPVerifierStore 接口。
创建一个可以从你创建的库里获取VerifierInfo
的SRPVerifierStore
接口实现。verifyUserChallenge(String, Object)
可用来集成现有的基于硬件令牌的模式(如 SafeWord 或 Radius)到 SRP 算法。这个接口方法只有当客户 SRPLoginModule 配置指定了 hasAuxChallenge 选项才被调用。创建 JNDI MBean。
创建一个开放 JNDI 可用的SRPVerifierStore
接口的 MBean,并开放任何所需的可配置参数。默认的org.jboss.security.srp.SRPVerifierStoreService
允许你实现它。你也可以用SRPVerifierStore
的一个 Java 属性文件实现来实现这个 MBean。
我们不推荐在产品环境里使用 SRPVerifierStore
接口的默认实现,因为它要求所有的密码
SRPVerifierStore
实现为给定用户提供了对 SRPVerifierStore.VerifierInfo
对象的访问。SRPService 在启动用户 SRP 会话来获取 SRP 算法所需参数时调用 getUserVerifier(String)
。
VerifierInfo 对象的元素
- username
- 用来验证的用户 ID 或用户名
- verifier
- 用户输入作为标识符凭证的单向哈希密码。
org.jboss.security.Util
类包含了一个calculateVerifier
方法,它执行密码的哈希算法。输出密码采用H(salt | H(username | ':' | password))
形式,其中H
是 RFC2945 定义的 SHA 安全哈希功能。用户名将使用 UTF-8 编码从字符串转换为 byte[]。 - salt
- 当数据库泄露时,随机数字用于增加对 verifier 密码数据库的 brute force 字典攻击的难度。当用户的现有明文密码进行哈希加密时,这个值应该根据一个强加密的随机数字算法生成。
- g
- SRP 算法的原始生成器。它可以是一个众所周知的固定参数而不用对每个用户进行设置。
org.jboss.security.srp.SRPConf
工具类为g
提供了几个设置,包括通过SRPConf.getDefaultParams().g()
获得的合适的默认值。 - N
- SRP 算法的 safe-prime 系数。它可以是一个众所周知的固定参数而不用对每个用户进行设置。
org.jboss.security.srp.SRPConf
工具类为g
提供了几个设置,包括通过SRPConf.getDefaultParams().g()
获得的合适的默认值。
例 12.13. SRPVerifierStore 接口
package org.jboss.security.srp; import java.io.IOException; import java.io.Serializable; import java.security.KeyException; public interface SRPVerifierStore { public static class VerifierInfo implements Serializable { public String username; public byte[] salt; public byte[] g; public byte[] N; } public VerifierInfo getUserVerifier(String username) throws KeyException, IOException; public void setUserVerifier(String username, VerifierInfo info) throws IOException; public void verifyUserChallenge(String username, Object auxChallenge) throws SecurityException; }
第 13 章 单点登录(SSO)
13.1. 关于 Web 应用程序的单点登录
单点登录(Single Sign On,SSO)允许到某个资源的验证可以授权对其他资源的访问。
非群集的 SSO 限制分享授权信息至相同虚拟机上的应用程序。此外,它在主机出现故障时无弹性可言。而群集 SSO 数据可以在多个虚拟主机里的应用程序间共享,对失效切换有一定弹性。而且,群集 SSO 可以从负载平衡器接收请求。
如果资源是未受保护的,用户根本不会被验证。如果用户访问了受保护的资源,用户将被验证。
SSO 的限制
- 不能在第三方边界传播数据
- SSO 只能在部署在 JBoss EAP 容器里的应用程序间使用。
- 只能用于容器管理的验证
- 你必须在应用程序
web.xml
里使用容器管理的授权元素,如<login-config>
。 - 要求 cookie
- SSO 通过浏览器 cookie 来保持且不支持 URL 重写。
- 区和安全域的限制
- 除非设置
requireReauthentication
参数为true
,配置相同 SSO 值的所有的 web 应用程序都应该共享web.xml
里的相同的区(Realm)配置以及安全域。你可以在 Host 元素或周围的 Engine 元素里嵌套 Realm 元素,但不能放在涉及的 web 应用程序里的 context.xml 元素里。jboss-web.xml
里配置的<security-domain>
必须在所有的 web 应用程序里一致。所有的安全集成必须接受相同的凭证(如用户名和密码)。
13.2. 关于 Web 应用程序的群集单点登录
jboss-web.xml
里完成的。
- Apache Tomcat ClusteredSingleSignOn
- Apache Tomcat IDPWebBrowserSSOValve
- SPNEGO-based SSO provided by PicketLink
13.3. 选择正确的 SSO 实现
如果你的机构已经使用了基于 Kerberos 的验证和授权系统,如 Microsoft Active Directory,你可以使用相同的系统来透明地验证运行在 JBoss EAP 里的应用程序。
如果你需要在运行在相同服务器组或实例里的应用程序间传播安全信息,你可以使用非群集的 SSO。这只要在应用程序的 jboss-web.xml
描述符里配置库(valve)就可以了。
如果你需要在运行在跨多个 JBoss EAP 实例的群集环境里的应用程序间传播安全信息,你可以使用群集的 SSO 库(Valve)。这只要在应用程序的 jboss-web.xml
描述符里进行配置就可以了。
13.4. 在 Web 应用程序里使用单点登录
单点登录(Single Sign On,SSO)是通过 web 和 Infinispan 子系统提供的。请使用下列步骤在 web 应用程序里配置 SSO。
前提条件
- 你需要一个处理验证和授权的配置好的安全域。
- 你需要
infinispan
子系统。对于受管域它位于full-ha
配置集里,而对于独立服务器,你需要使用standalone-full-ha.xml
配置。 web
cache-container
和 SSO cache-container 都必须存在。配置文件示例已经包含了web
cache-container,而一些配置也已经包含了 SSO cache-container。请使用下列命令来检查并启用 SSO cache-container。请注意,这些命令修改了受管域的full
配置集。对于独立服务器,你可以修改这些命令来使用其他的配置集,或者去掉命令行的/profile=full
部分。例 13.1. 检查
web
cache-container上面提及的配置集和配置在默认情况下包括web
cache-container。请使用下列命令来检验它的存在。如果你使用了不同的配置集,请用这个配置集的名称来替换ha
。/profile=ha/subsystem=infinispan/cache-container=web/:read-resource(recursive=false,proxies=false,include-runtime=false,include-defaults=true)
如果结果为success
,表示子系统存在。否则,你需要添加它。例 13.2. 添加
web
cache-container请使用下列三个命令来启用你的配置里的web
cache-container。修改配置集的名称以及其他参数。这里的参数是用于默认配置的。/profile=ha/subsystem=infinispan/cache-container=web:add(aliases=["standard-session-cache"],default-cache="repl",module="org.jboss.as.clustering.web.infinispan")
/profile=ha/subsystem=infinispan/cache-container=web/transport=TRANSPORT:add(lock-timeout=60000)
/profile=ha/subsystem=infinispan/cache-container=web/replicated-cache=repl:add(mode="ASYNC",batching=true)
例 13.3. 检查
SSO
cache-container运行下列管理 CLI 命令:/profile=ha/subsystem=infinispan/cache-container=web/:read-resource(recursive=true,proxies=false,include-runtime=false,include-defaults=true)
找到类似于"sso" => {
的输出:如果没有找到则表示 SSO cache-container 没有在你的配置里出现。例 13.4. 添加
SSO
cache-container/profile=ha/subsystem=infinispan/cache-container=web/replicated-cache=sso:add(mode="SYNC", batching=true)
- 你需要配置
web
子系统来使用 SSO。下面的命令在名为default-host
的虚拟服务器和 cookie 域domain.com
上启用了 SSO。缓存名称是sso
,重新验证是禁用的。/profile=ha/subsystem=web/virtual-server=default-host/sso=configuration:add(cache-container="web",cache-name="sso",reauthenticate="false",domain="domain.com")
- 你需要配置将共享 SSO 信息的每个应用程序以在
jboss-web.xml
里使用相同 <security-domain> 以及在web.xml
里使用相同的 Realm 元素。
群集 SSO 允许在不同的主机间共享验证信息,而非群集的 SSO 不允许。群集和非群集的 SSO 阀的配置方式相同,但群集 SSO 包含了 cacheConfig
、processExpiresInterval
和 maxEmptyLife
参数,它们控制持久数据的群集复制。
例 13.5. 群集 SSO 配置示例
tomcat
的安全域。
<jboss-web> <security-domain>tomcat</security-domain> <valve> <class-name>org.jboss.web.tomcat.service.sso.ClusteredSingleSignOn</class-name> <param> <param-name>maxEmptyLife</param-name> <param-value>900</param-value> </param> </valve> </jboss-web>
选项 | 描述 |
---|---|
cookieDomain |
用于 SSO cookie 的主机域。默认为
/ 。要允许 app1.xyz.com 和 app2.xyz.com 共享 SSO cookie,你可以设置 cookieDomain 为 xyz.com 。
|
maxEmptyLife |
只适用于群集 SSO。没有活动会话的 SSO 阀可被请求所使用的最长时间(秒)。正值允许正确处理节点的关闭,如果它是唯一带有附加到阀的会话的节点的话。如果 maxEmptyLife 被设置为
0 ,当本地会话复制时阀将终止,但会从群集应用程序里备份会话以供其他群集节点使用。允许阀超过其受管会话的生命周期给了用户进行其他请求的时间,以便失效切换到不同的节点,从而可以激活会话的备份。它默认为 1800 秒(30 分钟)。
|
processExpiresInterval |
只适用于群集 SSO。阀寻找和使已超过
MaxEmptyLife 的 SSO 实例失效的最长时间(秒)。默认为 60 秒(1 分钟)。
|
requiresReauthentication |
如果为 true,每个请求都使用缓存的凭证来重新验证安全域。如果为 false(默认值),对于这个阀来说,有效的 SSO cookie 就足够验证每个新的请求了。
|
应用程序可以通过调用 javax.servlet.http.HttpSession.invalidate()
方法在程序里使会话失效。
13.5. 关于 Kerberos
13.6. 关于 SPNEGO
13.7. 关于 Microsoft Active Directory
- 轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP),存储用户、主机、密码和其他资源的信息。
- Kerberos,提供网络上的安全验证。
- 域名服务(Domain Name Service,DNS)提供 IP 地址和网络上主机和其他设备的名称之间的映射。
13.8. 为 Web 应用程序配置 Kerberos 或 Microsoft Active Directory 桌面单点登录
要使用机构现有的基于 Kerberos 的验证和授权体系(如 Microsoft Active Directory)来验证你的 Web 或 EJB 应用程序,你可以使用 JBoss EAP 6 里内嵌的 JBoss Negotation 功能。如果你正确配置了你的 web 应用程序,成功的桌面或网络登录就足够透明地验证你的 we 应用程序,而不需要额外的登录提示。
JBoss EAP 6 和之前的版本有着一些值得注意的区别:
- 对于受管域的每个配置集或每个独立服务器来说,安全域都是集中配置的。它们不是部署本身的一部分。部署应该使用的安全域是在部署的
jboss-web.xml
或jboss-ejb3.xml
文件里命名的。 - 安全属性是作为安全域也是中央配置的一部分配置的。它们不是部署的一部分。
- 你无法再覆盖作为部署一部分的验证。然而,你可以添加一个 NegotiationAuthenticator 阀到
jboss-web.xml
描述符以实现相同的效果。这个值仍然要求在web.xml
里定义<security-constraint>
和<login-config>
元素。它们用于确定哪些资源是安全的。然而,所选的 auth-method 将被jboss-web.xml
里的 NegotiationAuthenticator 阀所替代。 - 安全域里的
CODE
属性现在使用一个简单的名称而不是全限定类名。下表展示了对 JBoss Negotiation 的类的映射。
简单名称 | 类名 | 目的 |
---|---|---|
Kerberos | com.sun.security.auth.module.Krb5LoginModule | Kerberos 登录模块 |
SPNEGO | org.jboss.security.negotiation.spnego.SPNEGOLoginModule | 启用 web 应用程序向 Kerberos 验证服务器验证的机制。 |
AdvancedLdap | org.jboss.security.negotiation.AdvancedLdapLoginModule | 和 LDAP 服务器而不是 Microsoft Active Directory 一起使用。 |
AdvancedAdLdap | org.jboss.security.negotiation.AdvancedADLoginModule | 和 Microsoft Active Directory LDAP 服务器一起使用。 |
The JBoss Negotiation Toolkit
is a debugging tool which is available for download from https://community.jboss.org/servlet/JiveServlet/download/16876-2-34629/jboss-negotiation-toolkit.war. It is provided as an extra tool to help you to debug and test the authentication mechanisms before introducing your application into production. It is an unsupported tool, but is considered to be very helpful, as SPNEGO can be difficult to configure for web applications.
过程 13.1. 设置 Web 或 EJB 应用程序的 SSO 验证
配置一个安全域来代表服务器的身份。如果需要则设置系统属性。
第一个安全域向目录服务验证容器自身。它需要使用一个接受某种静态登录机制的登录模块,因为这没有涉及真正的用户。这个例子使用了一个静态 principal 并引用了一个包含凭证的 Keytab 文件。下面通过 XML 片段进行阐述,但你应该使用管理控制台或 CLI 来配置你的安全域。<security-domain name="host" cache-type="default"> <authentication> <login-module code="Kerberos" flag="required"> <module-option name="storeKey" value="true"/> <module-option name="useKeyTab" value="true"/> <module-option name="principal" value="host/testserver@MY_REALM"/> <module-option name="keyTab" value="/home/username/service.keytab"/> <module-option name="doNotPrompt" value="true"/> <module-option name="debug" value="false"/> </login-module> </authentication> </security-domain>
配置第二个安全域来保护 web 或 EJB 应用程序。如果有必要请设置系统属性。
第二个安全域用来向 Kerberos 或 SPNEGO 验证服务器验证单独的用户。你需要至少一个登录模块来验证用户,另外一个则搜索适用于用户的角色。下面的 XML 片段展示了一个 SPNEGO 安全域示例。它包含了一个授权模块来映射角色和单独的用户。你也可以使用一个搜索验证服务器自己的角色的模块。<security-domain name="SPNEGO" cache-type="default"> <authentication> <!-- Check the username and password --> <login-module code="SPNEGO" flag="requisite"> <module-option name="password-stacking" value="useFirstPass"/> <module-option name="serverSecurityDomain" value="host"/> </login-module> <!-- Search for roles --> <login-module code="UserRoles" flag="required"> <module-option name="password-stacking" value="useFirstPass" /> <module-option name="usersProperties" value="spnego-users.properties" /> <module-option name="rolesProperties" value="spnego-roles.properties" /> </login-module> </authentication> </security-domain>
在
web.xml
里指定 security-constraint 和 login-config。web.xml
描述符包含了安全约束和登录配置的信息。下面是两者的示例。<security-constraint> <display-name>Security Constraint on Conversation</display-name> <web-resource-collection> <web-resource-name>examplesWebApp</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>RequiredRole</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>SPNEGO</auth-method> <realm-name>SPNEGO</realm-name> </login-config> <security-role> <description> role required to log in to the Application</description> <role-name>RequiredRole</role-name> </security-role>
在
jboss-web.xml
描述符里指定安全域和其他设置。在部署的jboss-web.xml
描述符里指定客户端安全域(这个例子里的第二个)的名称,指引你的应用程序来使用这个安全域。你无法再直接覆盖验证。相反,如果需要的话你可以在jboss-web.xml
里添加 NegotiationAuthenticator 为阀。<jacc-star-role-allow>
允许你使用星号(*)来匹配多个角色名,它是可选的。<jboss-web> <security-domain>java:/jaas/SPNEGO</security-domain> <valve> <class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name> </valve> <jacc-star-role-allow>true</jacc-star-role-allow> </jboss-web>
添加一个依赖关系到应用程序的
MANIFEST.MF
以定位 Negotiation 类。Web 应用程序需要在部署的META-INF/MANIFEST.MF
manifest 里添加一个org.jboss.security.negotiation
类的依赖关系,从而定义 JBoss Negotiation 类。下面是一个具有正确格式的条目。Manifest-Version: 1.0 Build-Jdk: 1.6.0_24 Dependencies: org.jboss.security.negotiation
你的 Web 应用程序通过 Kerberos、Microsoft Active Directory 或其他兼容 SPNEGO 的目录服务接受和验证凭证。如果用户在一个已经登录至目录服务的系统里运行这个应用程序,而要求的角色已经应用到用户,那么这个 Web 应用程序将不会再提示进行验证,从而实现了 SSO 功能。
第 14 章 应用程序里基于角色的安全性
14.1. 关于应用程序的安全性
14.2. 关于安全性审计
14.3. 关于安全性映射
14.4. 关于安全性扩展架构
这个架构的第一部分是 JAAS API。JAAS 是一个可插拔的框架,它为安全性架构和应用程序间提供了一个抽象层。
org.jboss.security.plugins.JaasSecurityManager
,它实现了 AuthenticationManager
和 RealmMapping
接口。基于对应的组件部署描述符的 <security-domain>
元素,JaasSecurityManager
集成到了 EJB 和 web 容器层。
JaasSecurityManagerService
MBean
JaasSecurityManagerService
MBean 服务管理安全性管理者。虽然它的名字以 Jaas 开始,但它处理的安全性管理者并不需要在其实现里使用 JAAS。这个名字反映的事实是,默认的安全性管理者实现是 JaasSecurityManager
。
JaasSecurityManagerService
的主要角色是具体化安全性管理者实现。你可以通过对 AuthenticationManager
和 RealmMapping
接口的其他实现来修改安全性管理者实现。
JaasSecurityManagerService
的第二个基础角色是提供一个 JNDI javax.naming.spi.ObjectFactory
实现以允许对 JNDI 名称和安全性管理者实现间绑定的简单的无代码管理。要启用安全性,可以通过 <security-domain>
部署描述符元素简化安全性管理者实现的 JNDI 名称。
JaasSecurityManagerService
绑定了一个 next naming system reference,提名自己为 java:/jaas
下的 JNDI ObjectFactory
。这允许了 java:/jaas/XYZ
形式的命名来作为 <security-domain>
元素的值,且 XYZ
安全域的安全管理者实例按需要创建,这是通过创建一个 SecurityManagerClassName
属性指定的类的实例,并使用采用安全域的名称的构造器来完成的。
注意
java:/jaas
前缀。虽然为了向后的兼容性,你可以这样做,但它会被忽略。
org.jboss.security.plugins.JaasSecurityDomain
是 JaasSecurityManager
的一个扩展,它添加了 KeyStore
、 KeyManagerFactory
和 TrustManagerFactory
以支持 SSL 和其他加密的用例。
关于安全性架构的更多信息以及实践示例,请参考 第 14.5 节 “关于 Java 认证和授权服务(JAAS)”。
14.5. 关于 Java 认证和授权服务(JAAS)
服务器组(受管域里)和服务器(独立服务器里)包含了安全域的配置。安全域包括合并验证、授权、映射和审计模块的信息以及配置细节。应用程序在 jboss-web.xml
里通过名字指定它需要哪个安全域。
应用程序专有的配置出现在一个或多个下列的四个文件里。
文件 | 描述 |
---|---|
ejb-jar.xml |
EJB 应用程序的部署描述符位于
META-INF 目录。请使用 ejb-jar.xml 来指定角色并映射到应用程序级别的 principal 上。你也可以将特定的方法和类限制到某些角色。这也可以用于其他和安全性无关的 EJB 专有的配置。
|
web.xml |
Java EE web 应用程序的部署描述符。请使用
web.xml 来声明应用程序用于验证和授权的安全域,以及资源和传输约束,如限制允许哪种类型的 HTTP 请求。你也可以在这个文件里配置简单的基于 web 的验证。它也可以用于和安全性无关的其他应用程序专有的配置。
|
jboss-ejb3.xml |
包含对
ejb-jar.xml 描述符的 JBoss 专有的扩展内容。
|
jboss-web.xml |
包含对
web.xml 描述符的 JBoss 专有的扩展内容。
|
注意
ejb-jar.xml
和 web.xml
是在 Java EE 规格里定义的。jboss-ejb3.xml
提供了对 ejb-jar.xml
的 JBoss 专有的扩展,而 jboss-web.xml
提供了对 web.xml
的 JBoss 专有的扩展。
Java 验证和授权服务(Java Authentication and Authorization Service,JAAS)是一个 Java 应用程序里用户级别安全性的框架,它使用可插拔的验证模块(Pluggable Authentication Module,PAM)。它被集成到 Java Runtime Environment(JRE)里。在 JBoss EAP 里,容器端的组件是 org.jboss.security.plugins.JaasSecurityManager
MBean。它提供了对 AuthenticationManager
和 RealmMapping
接口的默认实现。
JaasSecurityManager 使用 JAAS 软件包来实现 AuthenticationManager 和RealmMapping 接口行为。特别是,它的行为源于 JaasSecurityManager 已经分配的安全域里配置的登录模块实例的执行。登录模块实现了安全域的 principal 验证和角色映射行为。通过插入域的不同的登录模块配置,你可以在不同的安全域里使用 JaasSecurityManager。
EJBHome
方法的客户端方法调用。EJB 已经部署在服务器里,它的 EJBHome
接口方法已经使用 ejb-jar.xml
里的 <method-permission> 元素进行了保护。它使用 jboss-ejb3.xml
里的 <security-domain> 元素指定的 jwdomain
安全域。下面的图表展示了这些步骤,我们在后面将进行解释。

图 14.1. 安全的 EJB 方法调用的步骤
- 客户端执行了一个 JAAS 登录来建立用于验证的 principal 和凭证。这在图表里被标注为 Client Side Login。它也可以通过 JNDI 来执行。要执行 JAAS 登录,你可以创建一个 LoginContext 实例并传入要使用的配置的名称。在这里,配置的名称是
other
。这个一次性的登录将登录 principal 以及凭证和随后的所有 EJB 调用相关联。这个过程并不需要验证用户。客户端登录的性质取决于客户使用的登录模块配置。在这个例子里,other
客户端登录配置条目使用了ClientLoginModule
登录模块。这个模块绑定用户名和密码到 EJB 调用层以供服务器上之后的验证。客户端标识符不在客户端进行验证。 - 客户端包含
EJBHome
方法并在服务器上调用它。这个调用包含客户端传入的方法参数,以及来自客户端 JAAS 登录的用户标识符和凭证。 - 在服务器上,安全性拦截器验证调用方法的用户。这涉及了另外一个 JAAS 登录。
- 安全域确定了登录模块的选择。安全域的名字作为登录配置条目名称被传入
LoginContext
构造器。EJB 安全域是jwdomain
。如果 JAAS 验证成功,JAAS 主题将被创建。JAAS 主题将包括一个 PrincipalSet,它有如下内容:- 一个
java.security.Principal
实例,它对应部署安全环境的客户端标识符。 - 名为
Roles
的java.security.acl.Group
,它包含用户应用程序域的角色名称。类型为org.jboss.security.SimplePrincipal
的对象代表角色名称。这些对象按照ejb-jar.xml
里的约束和EJBContext.isCallerInRole(String)
方法实现检验对 EJB 方法的访问。 - 名为
CallerPrincipal
的可选java.security.acl.Group
,它包含一个对应应用程序域的调用者的标识符的org.jboss.security.SimplePrincipal
。CallerPrincipal 组成员是EJBContext.getCallerPrincipal()
方法返回的值。这个映射允许可操作安全环境里的 Principal 映射到应用程序已知的 Principal。在缺乏 CallerPrincipal 映射的情况下,可操作的 principal 和应用程序域 principal 是相同的。
- 服务器检验调用 EJB 方法的用户是否具有权限。执行这个授权涉及两个步骤:
- 获取被允许从 EJB 容器访问 EJB 方法的角色的名称。这些角色名称由
ejb-jar.xml
的 <role-name> 元素和包含被调用方法的 <method-permission> 元素来确定。 - 如果没有分配角色,或者方法是在一个 exclude-list 元素里指定的,那对这个方法的访问将被拒绝。否则,安全性拦截器将在安全管理者上调用
doesUserHaveRole
方法以检查调用者是否具有分配的角色名称。这个方法迭代角色名称并检查已验证的用户的Subject Roles
组是否包含具有分配的角色名称的 SimplePrincipal。如果任何角色名称是 Roles 组的成员,访问将被允许。而如果任何一个角色名称都不是成员,访问将被拒绝。 - 如果 EJB 使用一个自定义的安全代理,那这个方法调用将被委托给这个代理。如果安全大力拒绝了对调用者的访问,它将抛出
java.lang.SecurityException
。否则,对 EJB 方法的访问将被允许,且方法调用将传递给下一个容器拦截器。SecurityProxyInterceptor 处理这个检查且这个拦截器没有被显示。 - 对于 web 连接请求,web 服务器将检查匹配请求的资源和被访问的 HTTP 方法的、
web.xml
里定义的安全性约束。如果存在对于这个请求的约束,web 服务器将调用 JaasSecurityManager 来执行 principal 验证,从而确保用户角色和 principal 对象相关联。
14.6. 在应用程序里使用安全域
要在应用程序里使用安全域,首先你必须通过服务器配置文件或应用程序的描述符文件配置安全域。然后你必须添加必要的注解到使用安全域的 EJB。这个主题涵盖了在应用程序里使用安全域所需的步骤。
过程 14.1. 配置你的应用程序以使用安全域
定义安全域
你可以在服务器的配置文件或应用程序的描述符里定义安全域。在服务器的配置文件里配置安全域
安全域是在服务器配置文件的security
子系统里配置的。如果 JBoss EAP 实例运行在受管域里,配置文件应该是domain/configuration/domain.xml
。如果是独立服务器,则是standalone/configuration/standalone.xml
文件。other
、jboss-web-policy
和jboss-ejb-policy
都是 JBoss EAP 6 里默认提供的安全域。下面的 XML 示例是从服务器配置文件的security
子系统里复制的。<subsystem xmlns="urn:jboss:domain:security:1.2"> <security-domains> <security-domain name="other" cache-type="default"> <authentication> <login-module code="Remoting" flag="optional"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> <login-module code="RealmDirect" flag="required"> <module-option name="password-stacking" value="useFirstPass"/> </login-module> </authentication> </security-domain> <security-domain name="jboss-web-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> <security-domain name="jboss-ejb-policy" cache-type="default"> <authorization> <policy-module code="Delegating" flag="required"/> </authorization> </security-domain> </security-domains> </subsystem>
你可以按需要用管理控制台或 CLI 配置其他的安全域。在应用程序的描述符文件里配置安全域
安全域是在应用程序的WEB-INF/jboss-web.xml
文件里的<jboss-web>
元素的<security-domain>
子元素里指定的。下面的例子配置了一个名为my-domain
的安全域。<jboss-web> <security-domain>my-domain</security-domain> </jboss-web>
这只是你可以在WEB-INF/jboss-web.xml
描述符里指定的许多设置中的一个。
在 EJB 里添加必需的注解
你可以用@SecurityDomain
和@RolesAllowed
注解在 EJB 里配置安全性。下面的 EJB 代码示例限制了具有guest
角色的用户对other
安全域的访问。package example.ejb3; import java.security.Principal; import javax.annotation.Resource; import javax.annotation.security.RolesAllowed; import javax.ejb.SessionContext; import javax.ejb.Stateless; import org.jboss.ejb3.annotation.SecurityDomain; /** * Simple secured EJB using EJB security annotations * Allow access to "other" security domain by users in a "guest" role. */ @Stateless @RolesAllowed({ "guest" }) @SecurityDomain("other") public class SecuredEJB { // Inject the Session Context @Resource private SessionContext ctx; /** * Secured EJB method using security annotations */ public String getSecurityInfo() { // Session context injected using the resource annotation Principal principal = ctx.getCallerPrincipal(); return principal.toString(); } }
关于更多的代码示例,请参考 JBoss EAP 6 Quickstarts 集里的ejb-security
quickstart,你可以在红帽的客户门户找到这些例子。
14.7. 在 Servlet 里使用基于角色的安全性
jboss-web.xml
里指定的安全域处理的。
在你在 servlet 里使用基于角色的安全性之前,用来验证和授权访问的安全域需要在 JBoss EAP 容器里进行配置。
过程 14.2. 在 Servlet 里添加基于角色的安全性
在 servlet 和 URL 模式间添加映射。
使用web.xml
里的<servlet-mapping>
元素来映射单独的 servlet 和 URL 模式。下面的例子映射名为DisplayOpResult
的 servlet 到 URL 模式/DisplayOpResult
。<servlet-mapping> <servlet-name>DisplayOpResult</servlet-name> <url-pattern>/DisplayOpResult</url-pattern> </servlet-mapping>
添加安全约束到 URL 模式。
要映射 URL 模式到安全约束,可以使用<security-constraint>
。下面的例子约束了具有角色eap_admin
的 principal 对 URL 模式/DisplayOpResult
的访问。这个角色需要出现在安全域里。<security-constraint> <display-name>Restrict access to role eap_admin</display-name> <web-resource-collection> <web-resource-name>Restrict access to role eap_admin</web-resource-name> <url-pattern>/DisplayOpResult/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>eap_admin</role-name> </auth-constraint> <security-role> <role-name>eap_admin</role-name> </security-role> </security-constraint>
在 WAR 的
jboss-web.xml
里指定安全域添加安全域到 WAR 的jboss-web.xml
以连接 servlet 到配置好的安全域,它知道如何根据安区性约束验证和授权 principal。下面的例子使用名为acme_domain
的安全域。<jboss-web> ... <security-domain>acme_domain</security-domain> ... </jboss-web>
14.8. 在应用程序里使用第三方的验证系统
注意
context.xml
里,它现在直接在 jboss-web.xml
描述符里进行配置。context.xml
现在已被忽略了。
例 14.1. 基本的验证阀
<jboss-web> <valve> <class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name> </valve> </jboss-web>
例 14.2. 带有头部属性集的自定义阀
<jboss-web> <valve> <class-name>org.jboss.web.tomcat.security.GenericHeaderAuthenticator</class-name> <param> <param-name>httpHeaderForSSOAuth</param-name> <param-value>sm_ssoid,ct-remote-user,HTTP_OBLIX_UID</param-value> </param> <param> <param-name>sessionCookieForSSOAuth</param-name> <param-value>SMSESSION,CTSESSION,ObSSOCookie</param-value> </param> </valve> </jboss-web>
编写自定义的验证器超出了本文档的范畴。然而,下面的 Java 代码可以作为例子参考。
例 14.3. GenericHeaderAuthenticator.java
/* * JBoss, Home of Professional Open Source. * Copyright 2006, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.web.tomcat.security; import java.io.IOException; import java.security.Principal; import java.util.StringTokenizer; import javax.management.JMException; import javax.management.ObjectName; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.Realm; import org.apache.catalina.Session; import org.apache.catalina.authenticator.Constants; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.Response; import org.apache.catalina.deploy.LoginConfig; import org.jboss.logging.Logger; import org.jboss.as.web.security.ExtendedFormAuthenticator; /** * JBAS-2283: Provide custom header based authentication support * * Header Authenticator that deals with userid from the request header Requires * two attributes configured on the Tomcat Service - one for the http header * denoting the authenticated identity and the other is the SESSION cookie * * @author <a href="mailto:Anil.Saldhana@jboss.org">Anil Saldhana</a> * @author <a href="mailto:sguilhen@redhat.com">Stefan Guilhen</a> * @version $Revision$ * @since Sep 11, 2006 */ public class GenericHeaderAuthenticator extends ExtendedFormAuthenticator { protected static Logger log = Logger .getLogger(GenericHeaderAuthenticator.class); protected boolean trace = log.isTraceEnabled(); // JBAS-4804: GenericHeaderAuthenticator injection of ssoid and // sessioncookie name. private String httpHeaderForSSOAuth = null; private String sessionCookieForSSOAuth = null; /** * <p> * Obtain the value of the <code>httpHeaderForSSOAuth</code> attribute. This * attribute is used to indicate the request header ids that have to be * checked in order to retrieve the SSO identity set by a third party * security system. * </p> * * @return a <code>String</code> containing the value of the * <code>httpHeaderForSSOAuth</code> attribute. */ public String getHttpHeaderForSSOAuth() { return httpHeaderForSSOAuth; } /** * <p> * Set the value of the <code>httpHeaderForSSOAuth</code> attribute. This * attribute is used to indicate the request header ids that have to be * checked in order to retrieve the SSO identity set by a third party * security system. * </p> * * @param httpHeaderForSSOAuth * a <code>String</code> containing the value of the * <code>httpHeaderForSSOAuth</code> attribute. */ public void setHttpHeaderForSSOAuth(String httpHeaderForSSOAuth) { this.httpHeaderForSSOAuth = httpHeaderForSSOAuth; } /** * <p> * Obtain the value of the <code>sessionCookieForSSOAuth</code> attribute. * This attribute is used to indicate the names of the SSO cookies that may * be present in the request object. * </p> * * @return a <code>String</code> containing the names (separated by a * <code>','</code>) of the SSO cookies that may have been set by a * third party security system in the request. */ public String getSessionCookieForSSOAuth() { return sessionCookieForSSOAuth; } /** * <p> * Set the value of the <code>sessionCookieForSSOAuth</code> attribute. This * attribute is used to indicate the names of the SSO cookies that may be * present in the request object. * </p> * * @param sessionCookieForSSOAuth * a <code>String</code> containing the names (separated by a * <code>','</code>) of the SSO cookies that may have been set by * a third party security system in the request. */ public void setSessionCookieForSSOAuth(String sessionCookieForSSOAuth) { this.sessionCookieForSSOAuth = sessionCookieForSSOAuth; } /** * <p> * Creates an instance of <code>GenericHeaderAuthenticator</code>. * </p> */ public GenericHeaderAuthenticator() { super(); } public boolean authenticate(Request request, HttpServletResponse response, LoginConfig config) throws IOException { log.trace("Authenticating user"); Principal principal = request.getUserPrincipal(); if (principal != null) { if (trace) log.trace("Already authenticated '" + principal.getName() + "'"); return true; } Realm realm = context.getRealm(); Session session = request.getSessionInternal(true); String username = getUserId(request); String password = getSessionCookie(request); // Check if there is sso id as well as sessionkey if (username == null || password == null) { log.trace("Username is null or password(sessionkey) is null:fallback to form auth"); return super.authenticate(request, response, config); } principal = realm.authenticate(username, password); if (principal == null) { forwardToErrorPage(request, response, config); return false; } session.setNote(Constants.SESS_USERNAME_NOTE, username); session.setNote(Constants.SESS_PASSWORD_NOTE, password); request.setUserPrincipal(principal); register(request, response, principal, HttpServletRequest.FORM_AUTH, username, password); return true; } /** * Get the username from the request header * * @param request * @return */ protected String getUserId(Request request) { String ssoid = null; // We can have a comma-separated ids String ids = ""; try { ids = this.getIdentityHeaderId(); } catch (JMException e) { if (trace) log.trace("getUserId exception", e); } if (ids == null || ids.length() == 0) throw new IllegalStateException( "Http headers configuration in tomcat service missing"); StringTokenizer st = new StringTokenizer(ids, ","); while (st.hasMoreTokens()) { ssoid = request.getHeader(st.nextToken()); if (ssoid != null) break; } if (trace) log.trace("SSOID-" + ssoid); return ssoid; } /** * Obtain the session cookie from the request * * @param request * @return */ protected String getSessionCookie(Request request) { Cookie[] cookies = request.getCookies(); log.trace("Cookies:" + cookies); int numCookies = cookies != null ? cookies.length : 0; // We can have comma-separated ids String ids = ""; try { ids = this.getSessionCookieId(); log.trace("Session Cookie Ids=" + ids); } catch (JMException e) { if (trace) log.trace("checkSessionCookie exception", e); } if (ids == null || ids.length() == 0) throw new IllegalStateException( "Session cookies configuration in tomcat service missing"); StringTokenizer st = new StringTokenizer(ids, ","); while (st.hasMoreTokens()) { String cookieToken = st.nextToken(); String val = getCookieValue(cookies, numCookies, cookieToken); if (val != null) return val; } if (trace) log.trace("Session Cookie not found"); return null; } /** * Get the configured header identity id in the tomcat service * * @return * @throws JMException */ protected String getIdentityHeaderId() throws JMException { if (this.httpHeaderForSSOAuth != null) return this.httpHeaderForSSOAuth; return (String) mserver.getAttribute(new ObjectName( "jboss.web:service=WebServer"), "HttpHeaderForSSOAuth"); } /** * Get the configured session cookie id in the tomcat service * * @return * @throws JMException */ protected String getSessionCookieId() throws JMException { if (this.sessionCookieForSSOAuth != null) return this.sessionCookieForSSOAuth; return (String) mserver.getAttribute(new ObjectName( "jboss.web:service=WebServer"), "SessionCookieForSSOAuth"); } /** * Get the value of a cookie if the name matches the token * * @param cookies * array of cookies * @param numCookies * number of cookies in the array * @param token * Key * @return value of cookie */ protected String getCookieValue(Cookie[] cookies, int numCookies, String token) { for (int i = 0; i < numCookies; i++) { Cookie cookie = cookies[i]; log.trace("Matching cookieToken:" + token + " with cookie name=" + cookie.getName()); if (token.equals(cookie.getName())) { if (trace) log.trace("Cookie-" + token + " value=" + cookie.getValue()); return cookie.getValue(); } } return null; } }
第 15 章 移植
15.1. 应用程序安全性的修改
UsersRolesLoginModule
在 classpath 里查找书性文件。在以前的 JBoss EAP 版本里,放在 EAP_HOME/server/SERVER_NAME/conf/
下的属性文件位于 classpath 上且可以轻易地被 UsersRolesLoginModule
找到。在 JBoss EAP 6 里,目录结构已经发生了变化。属性文件必须打包在应用程序里,使其在 classpath 上可用。
重要
standalone/configuration/standalone.xml
或 domain/configuration/domain.xml
服务器配置文件里的 security-domains
下添加一个新的安全域:
<security-domain name="example"> <authentication> <login-module code="UsersRoles" flag="required"> <module-option name="usersProperties" value="${jboss.server.config.dir}/example-users.properties"/> <module-option name="rolesProperties" value="${jboss.server.config.dir}/example-roles.properties"/> </login-module> </authentication> </security-domain>
${jboss.server.config.dir}
指向 EAP_HOME/standalone/configuration/
目录。如果它运行在受管域里, ${jboss.server.config.dir}
指向 EAP_HOME/domain/configuration/
目录。
在 JBoss EAP 6 里,安全域名称里不再使用前缀 java:/jaas/
。
- 对于 Web 应用程序,你必须从
jboss-web.xml
里的安全域配置里删除这个前缀。 - 对于企业级应用程序,你必须从
jboss-ejb3.xml
里的安全域配置里删除这个前缀。这个文件已经替换了 JBoss EAP 6 里的jboss.xml
。
第 16 章 验证和授权
16.1. 关于验证
16.2. 关于授权
16.3. Java 认证和授权服务(JAAS)
16.4. 关于 Java 认证和授权服务(JAAS)
服务器组(受管域里)和服务器(独立服务器里)包含了安全域的配置。安全域包括合并验证、授权、映射和审计模块的信息以及配置细节。应用程序在 jboss-web.xml
里通过名字指定它需要哪个安全域。
应用程序专有的配置出现在一个或多个下列的四个文件里。
文件 | 描述 |
---|---|
ejb-jar.xml |
EJB 应用程序的部署描述符位于
META-INF 目录。请使用 ejb-jar.xml 来指定角色并映射到应用程序级别的 principal 上。你也可以将特定的方法和类限制到某些角色。这也可以用于其他和安全性无关的 EJB 专有的配置。
|
web.xml |
Java EE web 应用程序的部署描述符。请使用
web.xml 来声明应用程序用于验证和授权的安全域,以及资源和传输约束,如限制允许哪种类型的 HTTP 请求。你也可以在这个文件里配置简单的基于 web 的验证。它也可以用于和安全性无关的其他应用程序专有的配置。
|
jboss-ejb3.xml |
包含对
ejb-jar.xml 描述符的 JBoss 专有的扩展内容。
|
jboss-web.xml |
包含对
web.xml 描述符的 JBoss 专有的扩展内容。
|
注意
ejb-jar.xml
和 web.xml
是在 Java EE 规格里定义的。jboss-ejb3.xml
提供了对 ejb-jar.xml
的 JBoss 专有的扩展,而 jboss-web.xml
提供了对 web.xml
的 JBoss 专有的扩展。
Java 验证和授权服务(Java Authentication and Authorization Service,JAAS)是一个 Java 应用程序里用户级别安全性的框架,它使用可插拔的验证模块(Pluggable Authentication Module,PAM)。它被集成到 Java Runtime Environment(JRE)里。在 JBoss EAP 里,容器端的组件是 org.jboss.security.plugins.JaasSecurityManager
MBean。它提供了对 AuthenticationManager
和 RealmMapping
接口的默认实现。
JaasSecurityManager 使用 JAAS 软件包来实现 AuthenticationManager 和RealmMapping 接口行为。特别是,它的行为源于 JaasSecurityManager 已经分配的安全域里配置的登录模块实例的执行。登录模块实现了安全域的 principal 验证和角色映射行为。通过插入域的不同的登录模块配置,你可以在不同的安全域里使用 JaasSecurityManager。
EJBHome
方法的客户端方法调用。EJB 已经部署在服务器里,它的 EJBHome
接口方法已经使用 ejb-jar.xml
里的 <method-permission> 元素进行了保护。它使用 jboss-ejb3.xml
里的 <security-domain> 元素指定的 jwdomain
安全域。下面的图表展示了这些步骤,我们在后面将进行解释。

图 16.1. 安全的 EJB 方法调用的步骤
- 客户端执行了一个 JAAS 登录来建立用于验证的 principal 和凭证。这在图表里被标注为 Client Side Login。它也可以通过 JNDI 来执行。要执行 JAAS 登录,你可以创建一个 LoginContext 实例并传入要使用的配置的名称。在这里,配置的名称是
other
。这个一次性的登录将登录 principal 以及凭证和随后的所有 EJB 调用相关联。这个过程并不需要验证用户。客户端登录的性质取决于客户使用的登录模块配置。在这个例子里,other
客户端登录配置条目使用了ClientLoginModule
登录模块。这个模块绑定用户名和密码到 EJB 调用层以供服务器上之后的验证。客户端标识符不在客户端进行验证。 - 客户端包含
EJBHome
方法并在服务器上调用它。这个调用包含客户端传入的方法参数,以及来自客户端 JAAS 登录的用户标识符和凭证。 - 在服务器上,安全性拦截器验证调用方法的用户。这涉及了另外一个 JAAS 登录。
- 安全域确定了登录模块的选择。安全域的名字作为登录配置条目名称被传入
LoginContext
构造器。EJB 安全域是jwdomain
。如果 JAAS 验证成功,JAAS 主题将被创建。JAAS 主题将包括一个 PrincipalSet,它有如下内容:- 一个
java.security.Principal
实例,它对应部署安全环境的客户端标识符。 - 名为
Roles
的java.security.acl.Group
,它包含用户应用程序域的角色名称。类型为org.jboss.security.SimplePrincipal
的对象代表角色名称。这些对象按照ejb-jar.xml
里的约束和EJBContext.isCallerInRole(String)
方法实现检验对 EJB 方法的访问。 - 名为
CallerPrincipal
的可选java.security.acl.Group
,它包含一个对应应用程序域的调用者的标识符的org.jboss.security.SimplePrincipal
。CallerPrincipal 组成员是EJBContext.getCallerPrincipal()
方法返回的值。这个映射允许可操作安全环境里的 Principal 映射到应用程序已知的 Principal。在缺乏 CallerPrincipal 映射的情况下,可操作的 principal 和应用程序域 principal 是相同的。
- 服务器检验调用 EJB 方法的用户是否具有权限。执行这个授权涉及两个步骤:
- 获取被允许从 EJB 容器访问 EJB 方法的角色的名称。这些角色名称由
ejb-jar.xml
的 <role-name> 元素和包含被调用方法的 <method-permission> 元素来确定。 - 如果没有分配角色,或者方法是在一个 exclude-list 元素里指定的,那对这个方法的访问将被拒绝。否则,安全性拦截器将在安全管理者上调用
doesUserHaveRole
方法以检查调用者是否具有分配的角色名称。这个方法迭代角色名称并检查已验证的用户的Subject Roles
组是否包含具有分配的角色名称的 SimplePrincipal。如果任何角色名称是 Roles 组的成员,访问将被允许。而如果任何一个角色名称都不是成员,访问将被拒绝。 - 如果 EJB 使用一个自定义的安全代理,那这个方法调用将被委托给这个代理。如果安全大力拒绝了对调用者的访问,它将抛出
java.lang.SecurityException
。否则,对 EJB 方法的访问将被允许,且方法调用将传递给下一个容器拦截器。SecurityProxyInterceptor 处理这个检查且这个拦截器没有被显示。 - 对于 web 连接请求,web 服务器将检查匹配请求的资源和被访问的 HTTP 方法的、
web.xml
里定义的安全性约束。如果存在对于这个请求的约束,web 服务器将调用 JaasSecurityManager 来执行 principal 验证,从而确保用户角色和 principal 对象相关联。
16.5. Java 容器授权合约(JACC)
16.5.1. 关于 Java 容器授权合约(JACC)
16.5.2. 配置 Java 容器授权合约(JACC)的安全性
jboss-web.xml
来包含正确的参数。
要为安全域添加 JACC 支持,请添加 JACC
授权策略到安全域的授权栈里,并设置 required
标记。下面是一个带有 JACC 支持的安全域的例子。然而,安全域是在管理控制台或 CLI 里,而不是直接在 XML 里配置的。
<security-domain name="jacc" cache-type="default"> <authentication> <login-module code="UsersRoles" flag="required"> </login-module> </authentication> <authorization> <policy-module code="JACC" flag="required"/> </authorization> </security-domain>
jboss-web.xml
位于你的部署的 META-INF/
或 WEB-INF/
目录里,且包含用 web 容器的覆盖选项和其他的 JBoss 专有的配置。要使用启用了 JACC 的安全域,你需要包括 <security-domain>
元素并设置 <use-jboss-authorization>
元素为 true
。下面的应用程序是用上面的 JACC 安全域进行正确配置的。
<jboss-web> <security-domain>jacc</security-domain> <use-jboss-authorization>true</use-jboss-authorization> </jboss-web>
配置 EJB 使用安全域并使用 JACC 对于不同的 Web 应用程序是不同的。对于 EJB,你可以在 ejb-jar.xml
里为一个方法或方法组声明 method permissions。在 <ejb-jar>
元素里,任何子 <method-permission>
元素都包含关于 JACC 角色的信息。详情请参考示例配置。EJBMethodPermission
类是 Java EE 6 API 的一部分,且 http://docs.oracle.com/javaee/6/api/javax/security/jacc/EJBMethodPermission.html 里有相关的文档。
例 16.1. EJB 里的 JACC 方法权限示例
<ejb-jar> <method-permission> <description>The employee and temp-employee roles may access any method of the EmployeeService bean </description> <role-name>employee</role-name> <role-name>temp-employee</role-name> <method> <ejb-name>EmployeeService</ejb-name> <method-name>*</method-name> </method> </method-permission> </ejb-jar>
jboss-ejb3.xml
描述符里的 <security>
子元素里声明。除了安全域以外,你也可以指定 run-as principal,它可以修改运行 EJB 的 principal。
例 16.2. EJB 里的安全域声明示例
<security> <ejb-name>*</ejb-name> <security-domain>myDomain</s:security-domain> <run-as-principal>myPrincipal</s:run-as-principal> </s:security>
16.6. Java 容器验证 SPI(JASPI)
16.6.1. 关于 Java 容器验证 SPI(JASPI)的安全性
16.6.2. 配置 Java 容器验证 SPI(JASPI)的安全性
<authentication-jaspi>
元素到你的安全域里。其配置和标准的验证模块类似,但登录模块元素包含在 <login-module-stack>
元素里。它的配置的结构是:
例 16.3. authentication-jaspi
元素的结构
<authentication-jaspi> <login-module-stack name="..."> <login-module code="..." flag="..."> <module-option name="..." value="..."/> </login-module> </login-module-stack> <auth-module code="..." login-module-stack-ref="..."> <module-option name="..." value="..."/> </auth-module> </authentication-jaspi>
EAP_HOME/domain/configuration/domain.xml
或 EAP_HOME/standalone/configuration/standalone.xml
之前你需要完全停止 JBoss EAP。
附录 A. 参考
A.1. 包括的验证模块
Code
名称里的 Role
。
Code
值或完整名称(软件包限定)来引用模块。
验证模块
代码 | Client
|
分类 | org.jboss.security.ClientLoginModule
|
描述 |
这个登录模块的目的是当 JBoss EAP 充当客户时建立调用者标识符和凭证。它不应该作为用于实际的服务器验证的安全域的一部分。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
multi-threaded | true 或 false
| false
|
如果每个线程都有自己的 principal 和凭证存储,请将其设置为 true。false 则指定虚拟机里的所有线程都共享系统的标识符和凭证。
|
password-stacking
| useFirstPass 或 false
| false
|
设置为 useFirstPass 表示这个登录模块应该寻找存储在 LoginContext 里的信息以用作标识符。当堆积这个登录模块和其他模块时可以使用这个选项。
|
>restore-login-identity
| true 或 false
| false
|
如果在 login() 方法的开始遇到的标识符和凭证在 logout() 被调用后要重新存储,请将其设置为 true。
|
代码 | Certificate
|
分类 | org.jboss.security.auth.spi.BaseCertLoginModule
|
描述 |
这个登录模块的目的是基于
X509 Certificates 验证用户。其中一个用例是 web 应用程序的 CLIENT-CERT 验证。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
securityDomain
| 串 |
无
|
具有持有信任证书的信任库的 JSSE 配置的安全域的名称。
|
verifier
| 分类 |
无
|
用户登录证书检验的
org.jboss.security.auth.certs.X509CertificateVerifier 的类名。
|
代码 | CertificateUsers
|
分类 | org.jboss.security.auth.spi.UsersRolesLoginModule
|
描述 |
使用属性资源。第一个映射用户名和密码,第二个映射用户名和角色。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
unauthenticatedIdentity
| 字符串 |
无
|
定义应该分配给不包含验证信息的请求的 principal 名称。这允许不受保护的 servlet 调用不要求专有角色的 EJB 上的方法。这样的 principal 没有关联的角色且只访问未设置安全性的 EJB 或者和
unchecked permission 约束关联的 EJB。
|
password-stacking
| useFirstPass 或 false
| false
|
设置为
useFirstPass 表示这个登录模块应该寻找存储在 LoginContext 里的信息以用作标识符。当堆积这个登录模块和其他模块时可以使用这个选项。
|
hashAlgorithm | 字符串 |
无
|
用于 hash 密码的
java.security.MessageDigest 算法的名称。这个选项没有默认值,你必须显性地设置它来启用哈希算法。当指定了哈希算法时,CallbackHandler 里包含的明文密码将在作为 inputPassword 参数传递给 UsernamePasswordLoginModule.validatePassword 前进行 hash。保存在 users.properties 文件里的密码必须进行同等的 hash。关于 java.security.MessageDigest 和这个类支持的算法的更多信息,请参考 http://docs.oracle.com/javase/6/docs/api/java/security/MessageDigest.html。
|
hashEncoding
| base64 或 hex
| base64
|
如果设置了
hashAlgorithm ,哈希密码的字符串格式。
|
hashCharSet
| 字符串 |
容器的环境里的默认编码集。
|
将明文密码转换为字节队列的编码。
|
usersProperties
|
属性文件或资源的全限定文件路径
| users.properties
|
包含用户和密码间映射的文件。这个文件里的每个属性的格式都是
username=password 。
|
rolesProperties
| 属性文件或资源的全限定文件路径 | roles.properties
|
包含用户和密码间角色的文件。这个文件里的每个属性的格式都是
username=role1,role2,...,roleN 。
|
ignorePasswordCase
| true 或 false
| false
|
密码的比较是否应该忽略大小写。当哈希密码不明显时这对于编码是很重要的。
|
principalClass
| 全限定类名。 |
无
|
包含一个将 String 参数用作 principal 名称的构造器的
Principal 实现类。
|
roleGroupSeparator
|
单个字符
| . (单一句号)
|
用来将用户名从
rolesGroup 文件里的角色组名里分离的字符。
|
defaultUsersProperties
| 串 | defaultUsers.properties
|
如果未找到 usersProperties 文件所使用的资源或文件的名称。
|
defaultRolesProperties
| 串 | defaultRoles.properties
|
如果未找到
rolesProperties 文件所使用的资源或文件的名称。
|
hashUserPassword
| true 或 false
| true
|
当指定了
hashAlgorithm 时是否 hash 用户输入的密码。默认为 true 。
|
hashStorePassword
| true 或 false
| true
|
当指定了
hashAlgorithm 时是否 hash 从 getUsersPassword() 返回的存储密码。
|
digestCallback
| 全限定类名。 |
无
|
包含 pre 或 post 摘要内容(如 salt 值)的
org.jboss.crypto.digest.DigestCallback 实现的类名。它只有在指定了 hashAlgorithm 时才被使用。
|
storeDigestCallback
| 全限定类名。 |
无
|
包含 pre 或 post 摘要内容(如哈希存储密码的 salt 值)的
org.jboss.crypto.digest.DigestCallback 实现的类名。它只有在 hashStorePassword 为 true 且指定了 hashAlgorithm 时才被使用。
|
callback.option.STRING
| 不同的 | 无 |
所有以
callback.option. 为前缀的选项都会传递给 DigestCallback.init(Map) 方法。收入用户名总是通过 javax.security.auth.login.name 选项传递的,而输入/存储密码是通过 digestCallback 或 storeDigestCallback 的 javax.security.auth.login.password 选项来传递的。
|
代码 | CertificateRoles
|
分类 | org.jboss.security.auth.spi.CertRolesLoginModule
|
描述 |
这个登录模块扩展了 Certificate 登录模块以从属性文件添加角色映射能力。它使用和 Certificate 登录模块相同的所有选项,并添加了如下选项。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
rolesProperties
| 字符串 | roles.properties
|
包含分配给每个用户的资源或文件的名称。角色属性文件里的格式必须是 username=role1,role2,其中 username 是证书的 DN,不包括任何
= (等号)和空格字符。下面的例子是正确的格式:
CN\=unit-tests-client,\ OU\=Red\ Hat\ Inc.,\ O\=Red\ Hat\ Inc.,\ ST\=North\ Carolina,\ C\=US=JBossAdmin |
defaultRolesProperties
| 字符串 | defaultRoles.properties
|
如果未找到
rolesProperties 文件所使用的资源或文件的名称。
|
roleGroupSeparator
| 单个字符 | . (单一句号)
|
作为
roleProperties 文件里的角色组分隔符的字符。
|
代码 | Database |
分类 | org.jboss.security.auth.spi.DatabaseServerLoginModule
|
描述 |
支持验证和角色映射的基于 JDBC 的登录模块。这基于具有下列定义的两个逻辑表。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
dsJndiName
| JNDI 资源 |
无
|
保存验证信息的 JNDI 资源的名称。这个选项是必需的。
|
principalsQuery
| prepared SQL 语句 | select Password from Principals where PrincipalID=?
|
获取 principal 的信息的 prepared SQL 查询。
|
rolesQuery
| prepared SQL 语句 | select Role, RoleGroup from Roles where PrincipalID=?
|
获取角色信息的 prepared SQL 查询。它应该和
select Role, RoleGroup from Roles where PrincipalID=? 相等,这里的 Role 是角色名称而 RoleGroup 的值总是带有大写 R 的 Roles 或 CallerPrincipal 。
|
代码 | DatabaseCertificate
|
分类 | org.jboss.security.auth.spi.DatabaseCertLoginModule
|
描述 |
这个登录模块扩展了 Certificate 登录模块以从数据库表添加角色映射能力。它使用和 Certificate 登录模块相同的所有选项,并添加了如下选项。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
dsJndiName
| JNDI 资源 |
|
保存验证信息的 JNDI 资源的名称。这个选项是必需的。
|
rolesQuery
| prepared SQL 语句 | select Role,RoleGroup from Roles where PrincipalID=?
|
为了映射角色的 prepared SQL 语句。它应该和
select Role, RoleGroup from Roles where PrincipalID=? 相等,这里的 Role 是角色名称而 RoleGroup 的值总是带有大写 R 的 Roles 或 CallerPrincipal 。
|
suspendResume
| true 或 false
| true
|
在数据库操作期间现有的 JTA 事务是否应该被暂停。
|
代码 | Identity
|
分类 | org.jboss.security.auth.spi.IdentityLoginModule
|
描述 |
关联这个模块选项里指定的 principal 和任何针对这个模块验证的主题。所使用的 Principal 类的类型是
org.jboss.security.SimplePrincipal 。如果没有指定 principal 选项,那使用的名称是 guest 。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
principal
| 字符串 | guest
|
用于 principal 的名称。
|
roles
| 用逗号隔开的字符串的列表 |
无
|
将分配给主题的用逗号隔开的角色列表。
|
代码 | Ldap
|
分类 | org.jboss.security.auth.spi.LdapLoginModule
|
描述 |
当用户名和密码存储在可通过 JNDI LDAP 供应商访问的 LDAP 服务器上时进行的验证。许多选项不是必需的,因为它们可由 LDAP 供应商或系统环境来决定。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
java.naming.factory.initial
| 类名 | com.sun.jndi.ldap.LdapCtxFactory
| InitialContextFactory 实现的类名。
|
java.naming.provider.url
| ldap:// URL
|
无
|
LDAP 服务器的 URL。
|
java.naming.security.authentication
| none 、simple 或 SASL 机制的名称。
| simple
|
用于绑定 LDAP 服务器的安全级别。
|
java.naming.security.protocol
| 传输协议 |
如果未指定,则由供应商决定。
|
用于安全访问的传输协议,如 SSL。
|
java.naming.security.principal
| 字符串 |
无
|
用于验证调用者的 principal 的名称。它是根据下面描述的属性构建的。
|
java.naming.security.credentials
| 凭证类型 |
无
|
验证模式使用的凭证类型。其中一些例子包括哈希密码、明文密码、密钥或证书。如果没有指定这个属性,其行为将由服务供应商决定。
|
principalDNPrefix
| 字符串 |
无
|
添加到用户名以组成用户 DN 的前缀。你可以提示用户输入用户名并使用
principalDNPrefix 和 principalDNSuffix 构建全限定 DN。
|
principalDNSuffix
| 串 |
|
添加到用户名以组成用户 DN 的后缀。你可以提示用户输入用户名并使用
principalDNPrefix 和 principalDNSuffix 构建全限定 DN。
|
useObjectCredential
| true 或 false
|
false
|
凭证是否应该用
org.jboss.security.auth.callback.ObjectCallback 类型的回调方法作为不透明的对象、还是用 JAAS PasswordCallback 作为字符数组密码获得。这允许传递非字符数组的凭证信息到 LDAP 服务器。
|
rolesCtxDN
| 全限定的 DN |
无
|
用于搜索用户角色的上下文的全限定 DN。
|
userRolesCtxDNAttributeName
|
属性
|
无
|
包含搜索用户角色的上下文 DN 的用户对象里的属性。它和
rolesCtxDN 的区别是搜索用户角色的上下文可能对于每个用户都是唯一的。
|
rolesAttributeID
| 属性 | roles
|
包含用户角色的属性的名称。
|
rolesAttributeIsDN
| true 或 false
| false
| roleAttributeID 是否包含角色对象的全限定 DN。如果为 false,角色名将从上下文名称的 roleNameAttributeId 属性值里获取。某些目录模式,如 Microsoft Active Directory,要求这个属性的值为 true 。
|
rolesNameAttributeID
| 属性 | group
|
包含角色名称的
roleCtxDN 上下文里的属性的名称。如果 roleAttributeIsDN 属性为 true ,这个属性将被用来查找角色对象的 name 属性。
|
uidAttributeID
| 属性 | uid
| UserRolesAttributeDN 里对应用户 ID 的属性的名称。它被用来定位用户角色。
|
matchOnUserDN
| true 或 false
| false
|
对用户角色搜索是否应该匹配用户的全限定 DN 或只是用户名而已。如果为
true ,完整的用户 DN 将作为匹配值。如果为 false ,则只使用用户名来匹配 uidAttributeName 属性。
|
allowEmptyPasswords
| true 或 false
| true
|
是否允许空的密码。多数 LDAP 服务器将空密码视同匿名登录尝试。要拒绝空密码,请将它设置为 false。
|
代码 | LdapExtended
|
分类 | org.jboss.security.auth.spi.LdapExtLoginModule
|
描述 |
另外的一个使用搜索来定位绑定用户和关联角色的 LDAP 登录模块实现。角色队列递归地解析 DN 来导航分层的角色结构。它使用和 LDAP 模块相同的
java.naming 选项以及下列 LDAP 模块没有的选项。
这个验证以两步进行:
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
baseCtxDN
| 全限定的 DN |
无
|
开始用户搜索的顶层上下文的固定 DN。
|
bindDN
| 全限定的 DN |
无
|
用户和角色查询里用来绑定 LDAP 服务器的 DN。这个 DN 需要读取和搜索
baseCtxDN 和 rolesCtxDN 值上的权限。
|
bindCredential
| 字符串,可以进行加密。 |
无
|
用于
bindDN 的密码。如果指定了 jaasSecurityDomain ,它可以被加密。
|
jaasSecurityDomain
| JMX ObjectName |
无
|
用来解密
bindCredential 的 JaasSecurityDomain 的 JMX ObjectName 。密码的解密使用 JaasSecurityDomain.encrypt64(byte[]) 方法返回的格式。
|
baseFilter
| LDAP 过滤器字符串 |
无
|
用来定位要验证的用户的上下文的搜索过滤器。从登录模块回调方法里获得的输入用户名或用户 DN 将替换至过滤器里的
{0} 表达式。搜索过滤器的一个常见例子是 (uid={0}) 。
|
rolesCtxDN
| 全限定的 DN |
无
|
用于搜索用户角色的上下文的固定 DN。这不是实际角色的 DN,它是包含用户角色的对象所在的 DN。例如,在 Microsoft Active Directory 服务器里,它是用户帐号所在的 DN。
|
roleFilter
| LDAP 过滤器字符串 |
|
用来定位和验证用户相关联的角色的搜索过滤器。从登录模块回调方法里获得的输入用户名和用户 DN 将被替换过滤器里的
{0} 表达式。已验证的用户 DN 将替换过滤器里的 {1} 表达式。匹配输入用户名的搜索过滤器示例是 (member={0}) 。对应已验证的用户 DN 的例子是 (member={1}) 。
|
roleAttributeIsDN | true 或 false
| false
| roleAttributeID 是否包含角色对象的全限定 DN。如果为 false,角色名将从上下文名称的 roleNameAttributeId 属性值里获取。某些目录模式,如 Microsoft Active Directory,要求这个属性的值为 true 。
|
defaultRole
|
角色名称
|
无
|
用于所有已验证用户的角色
|
parseRoleNameFromDN
| true 或 false
| false
|
指定查询返回的 DN 是否包含 roleNameAttributeID。如果设置为
true ,将检查 DN 里是否有 roleNameATtributeID,如果为 false ,将不会检查。这个标记可以提高 LDAP 查询的性能。
|
parseUsername
| true 或 false
| false
|
指定 DN 是否对用户名进行解析的标记。如果为
true ,DN 将对用户名进行解析。如果为 false ,DN 将不对用户名进行解析。这个选项是和 usernameBeginString 及 usernameEndString 一起使用的。
|
usernameBeginString
|
字符串
|
无
|
定义将从 DN 的开头删除以显示用户名的字符串。这个选项是和
usernameEndString 一起使用的。
|
usernameEndString
|
字符串
|
无
|
定义将从 DN 的结尾删除以显示用户名的字符串。这个选项是和
usernameBeginString 一起使用的。
|
roleNameAttributeID
| 属性 | group
|
包含角色名称的
roleCtxDN 上下文里的属性的名称。如果 roleAttributeIsDN 属性为 true ,这个属性将被用来查找角色对象的 name 属性。
|
distinguishedNameAttribute
| 属性 | distinguishedName
|
包含用户 DN 的用户条目里的属性的名称。如果用户自身的 DN 包含特殊字符(如反斜杠)而阻止了正确的用户映射,这就是有必要的。如果这个属性不存在,条目的 DN 将会被使用。
|
roleRecursion
| 整数 | 0
|
角色搜索的递归级别数。禁用递归可将其设置为
0 。
|
searchTimeLimit
| 整数 | 10000 (10 秒)
|
用户或角色搜索的超时时间(毫秒)。
|
searchScope
| OBJECT_SCOPE, ONELEVEL_SCOPE, SUBTREE_SCOPE 中的一个
| SUBTREE_SCOPE
|
使用的搜索作用域
|
allowEmptyPasswords
| true 或 false
| true
|
是否允许空的密码。多数 LDAP 服务器将空密码视同匿名登录尝试。要拒绝空密码,请将它设置为 false。
|
代码 | RoleMapping
|
分类 | org.jboss.security.auth.spi.RoleMappingLoginModule
|
描述 |
映射作为验证过程的最终结果的角色到声明式角色。当你添加这个模块到安全域里时,它必须标记为
optional 。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
rolesProperties
| 属性文件或资源的全限定文件路径 | roles.properties
|
映射角色到替代角色的属性文件或资源的全限定文件路径。其格式是
original_role=role1,role2,role3 。
|
replaceRole
| true 或 false
| false
|
是否添加当前的角色,或者用映射的角色替换当前的角色。设为
true 则进行替换。
|
代码 | RunAs
|
分类 | Class: org.jboss.security.auth.spi.RunAsLoginModule
|
描述 |
这是一个 Helper 模块,它在验证的登录阶段将
run as 角色推入栈,并在提交或中止阶段从栈里弹出 run as 角色。这个登录模块为其他必须访问安全资源以执行验证的登录模块(如访问安全 EJB 的登录模块)提供了一个角色。在要求 run as 角色的登录模块建立之前,你必须先配置好 RunAsLoginModule 。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
roleName
| 角色名称 | nobody
|
在登录阶段用作
run as 角色的角色的名称。
|
代码 | Simple
|
分类 | org.jboss.security.auth.spi.SimpleServerLoginModule
|
描述 |
用于测试目的的快速设置安全性的模块。它实现了下列简单的算法:
|
Simple
模块选项
Simple
模块没有选项。
代码 | ConfiguredIdentity
|
分类 | org.picketbox.datasource.security.ConfiguredIdentityLoginModule
|
描述 |
关联这个模块选项里指定的 principal 和任何针对这个模块验证的主题。所使用的 Principal 类的类型是
org.jboss.security.SimplePrincipal 。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
principal
| principal 的名称。 | guest
|
将和针对这个模块验证的任何主题关联的 principal。
|
代码 | SecureIdentity
|
分类 | org.picketbox.datasource.security.SecureIdentityLoginModule
|
描述 |
提供这个模块只是为了和之前的系统兼容。它允许你加密密码并和静态 principal 一起使用这个密码。如果你的应用程序使用了
SecureIdentity ,请考虑使用密码库机制。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
username
| 串 | 无 | 用于验证的用户名。 |
password
| 加密的字符串 | 无 |
用于验证的密码。要加密这个密码,请在命令行直接使用这个模块。
将这个命令的运行结果粘贴到模块选项的 value 字段。
|
managedConnectionFactoryName
| JCA 资源 | 无 |
数据源的 JCA 连接工厂的名称。
|
代码 | PropertiesUsers
|
分类 | org.jboss.security.auth.spi.PropertiesUsersLoginModule
|
描述 |
使用一个属性文件来存储用户名和密码。它没有提供授权(角色映射)。这个模块只适合于测试用途。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
properties
| Java 属性文件或资源的全限定文件路径和名称。 | 无 |
用于验证的包含用户名和明文密码的属性文件。
|
代码 | SimpleUsers
|
分类 | org.jboss.security.auth.spi.SimpleUsersLoginModule
|
描述 |
这个登录模块在一个 Java 属性文件里保存了用户名和明文密码。这只是用于测试目的,不适合用于产品环境里。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
username
| 串 | 无 | 用于验证的用户名。 |
password
| 串 | 无 | 用于验证的明文密码。 |
代码 | LdapUsers
|
分类 | org.jboss.security.auth.spi.LdapUsersLoginModule
|
描述 | LdapUsers 模块被 ExtendedLDAP 和 AdvancedLdap 模块取代。
|
代码 | Kerberos
|
分类 | com.sun.security.auth.module.Krb5LoginModule
|
描述 |
用 GSSAPI 执行Kerberos 登录验证。这个模块不是 Sun Microsystems 提供的 API 里的安全框架的一部分。细节可以在 http://docs.oracle.com/javase/1.4.2/docs/guide/security/jaas/spec/com/sun/security/auth/module/Krb5LoginModule.html 里找到。这个模块需要和另外一个处理验证和角色映射的模块配对。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
storekey
| true 或 false
| false |
是否添加
KerberosKey 到主题的私有凭证。
|
doNotPrompt
| true 或 false
| false |
如果设置为
true ,用户将不会被提示输入密码。
|
useTicketCache
|
布尔值,
. true 或 false 。
| false |
如果为
true ,GTG 将从票据缓存里获取。如果为 false ,将不会使用票据缓存。
|
ticketcache
| 代表 Kerberos 票据缓存的文件或资源。 |
默认值取决于你所使用的操作系统。
| 票据缓存的位置。 |
useKeyTab
| true 或 false
| false | 是否从密钥表文件里获取 principal 的密钥。 |
keytab
| 代表 Kerberos keytab 的文件或资源。 |
操作系统的 Kerberos 配置文件的位置,或者
/home/user/krb5.keytab 。
| 密钥表文件的位置。 |
principal
| 字符串 | 无 |
Principal 的名称。这可以是简单的用户名或服务名,如
host/testserver.acme.com 。或者当密钥表包含多个 principal 时,使用它而不是从密钥表里获取 principal。
|
useFirstPass
| true 或 false
| false |
是否以从
javax.security.auth.login.name 和 javax.security.auth.login.password 为关键字从模块的共享状态获取用户名和密码。如果验证失败,不会进行重试。
|
tryFirstPass
| true 或 false
| false |
和
useFirstPass 相同,但如果验证失败,模块将使用 CallbackHandler 来获取新的用户名和密码。如果第二次验证失败,将报告给调用的应用程序。
|
storePass
| true 或 false
| false |
是否在模块的共享状态里保存用户名和密码。如果关键字已存在于共享内存里,或者验证失败的话,这都不会发生。
|
clearPass
| true 或 false
| false |
设置它为
true 在两个验证阶段都完成后从共享内存里清除用户名和密码。
|
代码 | SPNEGOUsers
|
分类 | org.jboss.security.negotiation.spnego.SPNEGOLoginModule
|
描述 |
允许在 Microsoft Active Directory 服务器或其他支持 SPNEGO 的环境里进行 SPNEGO 验证。SPNEGO 也可以包含 Kerberos 凭证。这个模块需要和另外一个处理验证和角色映射的模块配对。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
storeKey
| true 或 false
| false
|
是否保存密钥。
|
useKeyTab
| true 或 false
| false
|
是否使用密钥表。
|
principal
|
代表 Kerberos 验证的 principal 的字符串。
|
无
|
用于验证的 principal 的名称。
|
keyTab
|
代表 keytab 的文件或资源。
| none
|
密钥表的位置。
|
doNotPrompt
| true 或 false
| false
|
是否提示输入密码。
|
debug
| true 或 false
| false
|
是否记录更冗余的信息以用于调试。
|
代码 | AdvancedLdap |
分类 | org.jboss.security.negotiation.AdvancedLdapLoginModule
|
描述 |
提供额外功能的模块,如 SASL 和对 JAAS 安全域的使用。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
bindAuthentication
|
串
|
无
|
用于绑定到目录服务器的 SASL 验证的类型。
|
jassSecurityDomain
| string
|
无
|
要使用的 JAAS 安全域的名称。
|
java.naming.provider.url
| string
|
无
|
目录服务器的 URI.
|
baseCtxDN
|
全限定标识名(DN)。
|
无
|
要用作搜索基础的标识名。
|
baseFilter
|
代表 LDAP 搜索过滤器的字符串。
|
无
|
用于缩减搜索结果的过滤器。
|
roleAttributeID
|
代表 LDAP 属性的字符串。
|
无
|
包含授权角色的名称的 LDAP 属性。
|
roleAttributeIsDN
| true 或 false
| false
|
这个角色属性是否是标识名(Distinguished Name,DN)。
|
roleNameAttributeID
|
代表 LDAP 属性的字符串。
|
无
|
包含实际角色属性的
RoleAttributeId 里所包含的属性。
|
recurseRoles
| true 或 false
| false
|
是否递归地搜索
RoleAttributeId 里的角色。
|
代码 | AdvancedADLdap |
分类 | org.jboss.security.negotiation.AdvancedADLoginModule
|
描述 |
这个模块扩展了
AdvancedLdap 登录模块,并添加额外的和 Microsoft Active Directory 相关的参数。
|
代码 | UsersRoles |
分类 | org.jboss.security.auth.spi.UsersRolesLoginModul
|
描述 |
支持存储在两个不同属性文件里的多个用户和角色的简单登录模块。
|
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
usersProperties
|
文件或资源的路径。
| users.properties
|
包含用户-密码映射的文件或资源。这个文件的格式是
user=hashed-password 。
|
rolesProperties
|
文件或资源的路径。
| roles.properties
|
包含用户-角色映射的文件或资源。这个文件的格式是
username=role1,role2,role3 。
|
password-stacking
| useFirstPass 或 false
| false
| useFirstPass 的值表示这个登录模块应该首先查看存储在 LoginContext 里关于这个标识符的信息。当堆积这个登录模块和其他模块时可以使用这个选项。
|
hashAlgorithm
|
代表密码的哈希算法的字符串。
| none
|
用于 hash 密码的
java.security.MessageDigest 算法的名称。这个选项没有默认值,你必须显性地设置它来启用哈希算法。当指定了 hashAlgorithm 时,CallbackHandler 里包含的明文密码将在作为 inputPassword 参数传递给 UsernamePasswordLoginModule.validatePassword 前进行 hash。保存在 users.properties 文件里的密码必须进行同等的 hash。
|
hashEncoding
| base64 或 hex
| base64
|
如果设置了 hashAlgorithm,哈希密码的字符串格式。
|
hashCharset
|
字符串
|
容器的运行时环境里的默认编码集。
|
将明文密码转换为字节队列的编码。
|
unauthenticatedIdentity
|
principal 名称
|
无
|
定义分配给不包含验证信息的请求的 principal 名称。这允许不受保护的 servlet 调用不要求专有角色的 EJB 上的方法。这样的 principal 没有关联的角色且只访问未设置安全性的 EJB 或者和
unchecked permission 约束关联的 EJB。
|
验证模块是 org.jboss.security.LoginModule
的实现。关于创建自定义验证模块的更多信息,请参考相关的 API 文档。
A.2. 包括的授权模块
代码 | 类 |
---|---|
DenyAll | org.jboss.security.authorization.modules.AllDenyAuthorizationModule |
PermitAll | org.jboss.security.authorization.modules.AllPermitAuthorizationModule |
Delegating | org.jboss.security.authorization.modules.DelegatingAuthorizationModule |
Web | org.jboss.security.authorization.modules.WebAuthorizationModule |
JACC | org.jboss.security.authorization.modules.JACCAuthorizationModule |
A.3. 包括的安全映射模块
代码 | 类 |
---|---|
PropertiesRoles | org.jboss.security.mapping.providers.role.PropertiesRolesMappingProvider |
SimpleRoles | org.jboss.security.mapping.providers.role.SimpleRolesMappingProvider |
DeploymentRoles | org.jboss.security.mapping.providers.DeploymentRolesMappingProvider |
DatabaseRoles | org.jboss.security.mapping.providers.role.DatabaseRolesMappingProvider |
LdapRoles | org.jboss.security.mapping.providers.role.LdapRolesMappingProvider |
A.4. 包括的安全审计供应商模块
代码 | 类 |
---|---|
LogAuditProvider | org.jboss.security.audit.providers.LogAuditProvider |
A.5. jboss-web.xml 配置参考
jboss-web.xml
是你的部署的 WEB-INF
或 META-INF
里的一个文件。它包含 JBoss Web 容器对 Servlet 3.0 规格所添加的功能的配置信息。Servlet 3.0 规格所专有的设置位于相同目录下的 web.xml
里。
jboss-web.xml
文件里的顶层元素是 <jboss-web>
元素。
许多可用的设置将应用程序的 web.ml
里设置的要求映射到本地资源。关于 web.xml
设置的解释,请访问 http://docs.oracle.com/cd/E13222_01/wls/docs81/webapp/web_xml.html。
web.xml
要求 jdbc/MyDataSource
,jboss-web.xml
可能映射全局数据源 java:/DefaultDS
来满足这个要求。WAR 使用全局数据源 jdbc/MyDataSource
来满足要求。
属性 | 描述 |
---|---|
env-entry |
对
web.xml 要求的 env-entry 的映射。
|
ejb-ref |
对
web.xml 要求的 ejb-ref 的映射。
|
ejb-local-ref |
对
web.xml 要求的 ejb-local-ref 的映射。
|
service-ref |
对
web.xml 要求的 service-ref 的映射。
|
resource-ref |
对
web.xml 要求的 resource-ref 的映射。
|
resource-env-ref |
对
web.xml 要求的 resource-env-ref 的映射。
|
message-destination-ref |
对
web.xml 要求的 message-destination-ref 的映射。
|
persistence-context-ref |
对
web.xml 要求的 persistence-context-ref 的映射。
|
persistence-unit-ref |
对
web.xml 要求的 persistence-unit-ref 的映射。
|
post-construct |
对
web.xml 要求的 post-context 的映射。
|
pre-destroy |
对
web.xml 要求的 pre-destroy 的映射。
|
data-source |
对
web.xml 要求的 data-source 的映射。
|
context-root | 应用程序的根上下文。默认值是部署的名称(不带 .war 后缀)。 |
virtual-host | 应用程序接受请求的 HTTP 虚拟主机的名称。它指向 HTTP Host 头部的内容。 |
annotation | 描述应用程序使用的注解。更多信息请参考 <annotation>。 |
listener | 描述应用程序使用的 listener。更多信息请参考 <listener>。 |
session-config | 这个元素和 web.xml 的 <session-config> 元素的功能一样,包括它只是出于兼容性的考虑。 |
valve | 描述应用程序使用的阀(Valve)。更多信息请参考 <valve>。 |
overlay | 添加至应用程序的覆盖(Overlay)的名称。 |
security-domain | 应用程序使用的安全域的名称。安全域自身是通过基于 Web 的管理控制台或管理 CLI 来配置的。 |
security-role | 这个元素和 web.xml 的 <security-role> 元素的功能一样,它只是作为兼容性被包括的。 |
use-jboss-authorization | 如果出现这个元素并包含了大小写敏感的值 “true”,JBoss Web 授权栈将被使用。如果它没出现或包含非 “true” 的值,那只会使用 Java EE 规格里指定的授权机制。这个元素是 JBoss EAP 6 里新引入的。 |
disable-audit | 如果出现这个元素,Web 安全审计将被禁用。否则,它将被启用。Web 安全审计不是 Java EE 规格的一部分。这个元素是 JBoss EAP 6 里新引入的。 |
disable-cross-context | 如果为 false ,应用程序能够调用另外一个应用程序上下文。它默认为 true 。 |
描述应用程序使用的注解。下表列出了 <annotation>
的子元素。
属性 | 描述 |
---|---|
class-name |
注解的类名
|
servlet-security |
代表了 servlet 安全性的元素,如
@ServletSecurity 。
|
run-as |
代表了 run-as 信息的元素,如
@RunAs 。
|
multi-part |
代表了 multi-part 信息的元素,如
@MultiPart 。
|
描述 listener。下表列出了 <listener>
的子元素。
属性 | 描述 |
---|---|
class-name |
Listener 的类名
|
listener-type | condition 元素的列表,表示添加哪种 listener 到应用程序的 Context 里。有效值为:
|
module |
包含 listener 类的模块的名称。
|
param |
包含两个子元素的参数:
<param-name> 和 <param-value> 。
|
描述应用程序的库。它包含和 <listener> 相同的配置元素。
A.6. EJB 安全参数引用
元素 | 描述 |
---|---|
<security-identity>
|
包含从属于 EJB 的安全标识符的子元素。
|
<use-caller-identity />
|
指定 EJB 使用和调用者相同的安全标识符。
|
<run-as>
|
包含一个
<role-name> 元素。
|
<run-as-principal>
|
如果指定,则表示分配给转出调用的 principal。如果不指定,分配给转出调用的 principal 是
anonymous 。
|
<role-name>
|
指定 EJB 应该以什么角色运行。
|
<description>
|
描述
. <role-name> 里命名的角色。
|
例 A.1. 安全标识符示例
<servlet>
里。
<ejb-jar> <enterprise-beans> <session> <ejb-name>ASessionBean</ejb-name> <security-identity> <use-caller-identity/> </security-identity> </session> <session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as> <description>A private internal role</description> <role-name>InternalRole</role-name> </run-as> </security-identity> </session> <session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as-principal>internal</run-as-principal> </security-identity> </session> </enterprise-beans> </ejb-jar>
附录 B. Revision History
修订历史 | |||
---|---|---|---|
修订 1.0.0-2 | Mon Jan 6 2014 | ||
| |||
修订 1.0.0-1 | Mon Jan 06 2014 | ||
|