安全指南
适用于红帽 JBoss 企业版应用程序平台 6
摘要
部分 I. 红帽 JBoss 企业版应用程序平台 6 的安全性
第 1 章 简介
1.1. 关于 JBoss 企业版应用程序平台 6(JBoss EAP 6)
1.2. 关于 JBoss 企业版应用程序平台 6 的安全性
第 2 章 安全概述
2.1. 关于声明式安全性
2.1.1. Java EE 的声明式安全性概述
ejb-jar.xml
和 web.xml
部署描述符来设置的。
2.1.2. 安全引用
图 2.1. 安全角色引用模型
role-nameType
属性值作为 isCallerInRole(String)
方法的参数使用。通过使用 isCallerInRole
方法,组件可以检验调用者是否具有用 <security-role-ref> 或 <role-name> 声明的角色。<role-name> 元素值必须通过 <role-link> 链接到 <security-role> 元素。isCallerInRole
的典型用法是执行一个无法用基于角色的 <method-permissions> 元素定义的安全检查。
例 2.1. ejb-jar.xml 描述符文件片段
<!-- A sample ejb-jar.xml fragment --> <ejb-jar> <enterprise-beans> <session> <ejb-name>ASessionBean</ejb-name> ... <security-role-ref> <role-name>TheRoleICheck<role-name> <role-link>TheApplicationRole</role-link> </security-role-ref> </session> </enterprise-beans> ... </ejb-jar>
注意
例 2.2. web.xml 描述符文件片段
<web-app> <servlet> <servlet-name>AServlet</servlet-name> ... <security-role-ref> <role-name>TheServletRole</role-name> <role-link>TheApplicationRole</role-link> </security-role-ref> </servlet> ... </web-app>
2.1.3. 安全标识符
图 2.2. J2EE 安全标识符数据模型
EJBContext.getCallerPrincipal()
方法所看到的调用者的标识符。而调用者的安全角色被设置为 <run-as> 或 <role-name> 元素值指定的单一角色。
<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> </enterprise-beans> <!-- ... --> </ejb-jar>
anonymous
的 principal 将分配给所有的转出调用。如果你想用其他的 principal 关联这个调用,你必须将 <run-as-principal> 和 jboss.xml
文件里的 bean 进行关联。下列代码片段将名为 internal
的 principal 和前面例子里的 RunAsBean
进行关联。
<session> <ejb-name>RunAsBean</ejb-name> <security-identity> <run-as-principal>internal</run-as-principal> </security-identity> </session>
web.xml
文件的 servlet 定义里也是可用的。下面的例子展示了如何将角色 InternalRole
分配给 servlet:
<servlet> <servlet-name>AServlet</servlet-name> <!-- ... --> <run-as> <role-name>InternalRole</role-name> </run-as> </servlet>
principal
相关联。jboss-web.xml
文件里的 <run-as-principal> 元素用于和 run-as
角色一起使用的专有 principal。下列代码片段展示了如何将名为 internal
的 principal 关联至上面的 servlet。
<servlet> <servlet-name>AServlet</servlet-name> <run-as-principal>internal</run-as-principal> </servlet>
2.1.4. 安全角色
security-role-ref
或 security-identity
引用的安全角色名称需要映射到应用程序所声明的其中一个角色。应用程序组装者通过声明 security-role
来定义安全角色。role-name
值是一个逻辑的应用程序角色名,如 Administrator、Architect、alesManager 等等。
security-role
元素只被用来映射 security-role-ref/role-name
值到组件角色引用的逻辑角色。用户的角色是应用程序的安全管理者动态分配的。JBoss 不要求定义 security-role
元素来声明方法权限。然而,我们仍然推荐使用 security-role
元素以确保跨应用服务器的可移植性且便于部署描述符的维护。
例 2.3. 解释 security-role 元素用法的 ejb-jar.xml 描述符片段。
<!-- A sample ejb-jar.xml fragment --><ejb-jar><assembly-descriptor><security-role><description>The single application role</description><role-name>TheApplicationRole</role-name></security-role></assembly-descriptor></ejb-jar>
例 2.4. 解释 security-role 元素用法的 web.xml 描述符片段。
<!-- A sample web.xml fragment --><web-app><security-role><description>The single application role</description><role-name>TheApplicationRole</role-name></security-role></web-app>
2.1.5. EJB 方法权限
图 2.3. J2EE 的 method-permission 元素
method-permission
元素都包含一个或多个定义逻辑角色的 role-name 子元素,这些逻辑角色可以访问 method-child 元素确定的 EJB 方法。你也可以指定 unchecked
而不是 role-name
元素来声明任何验证用户都可以访问 method-child 元素确定的 EJB 方法。此外,你可以声明无人可以访问具有 exclude-list
元素的方法。如果 EJB 具有没有用 method-permission
元素声明可以访问的方法,那 EJB 方法默认是不能被使用的。这等同于将方法默认放入 exclude-list
元素里。
图 2.4. J2EE 方法元素
<method><ejb-name>EJBNAME</ejb-name><method-name>*</method-name></method>
<method><ejb-name>EJBNAME</ejb-name><method-name>METHOD</method-name></method>
<method><ejb-name>EJBNAME</ejb-name><method-name>METHOD</method-name><method-params><method-param>PARAMETER_1</method-param><!-- ... --><method-param>PARAMETER_N</method-param></method-params></method>
method-intf
元素可以用来区分 EJB 里在 home 和 remote 接口都定义了且具有相同名称和签名的方法。
method-permission
用法的完整示例。
例 2.5. 解释 method-permission 元素用法的 ejb-jar.xml 描述符片段。
<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 AardvarkPayroll bean </description><role-name>employee</role-name><method><ejb-name>AardvarkPayroll</ejb-name><method-name>findByPrimaryKey</method-name></method><method><ejb-name>AardvarkPayroll</ejb-name><method-name>getEmployeeInfo</method-name></method><method><ejb-name>AardvarkPayroll</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>
2.1.6. EJB 的安全性注解
@DeclareRoles
- 它指定了代码里声明每个安全角色。关于配置角色的信息,请参考 Java EE 5 TutorialDeclaring Security Roles Using Annotations。
@RolesAllowed
、@PermitAll
和@DenyAll
- 它指定注解的方法权限。关于配置注解的方法权限的信息,请参考 Java EE 5 TutorialSpecifying Method Permissions Using Annotations。
@RunAs
- 它配置组件的传播安全标识符。关于使用注解配置传播安全标识符的信息,请参考 Java EE 5 TutorialConfiguring a Component’s Propagated Security Identity。
2.1.7. Web 内容安全约束
web.xml
的 security-constraint 元素来声明的。
图 2.5. Web 内容安全约束
NONE
、INTEGRAL
和 CONFIDENTIAL
。NONE
表示应用程序不要求任何传输保证。INTEGRAL
表示应用程序要求客户和服务器间发送的数据以传输中不可以更改的方式进行。CONFIDENTIAL
表示应用程序要求以防止其他实体观察传输内容的方式进行传输。大多数情况下,INTEGRAL
或 CONFIDENTIAL
标记的出现都表示要求使用 SSL。
图 2.6. Web 登录配置
BASIC
、DIGEST
、FORM
和 CLIENT-CERT
。 <realm-name> 子元素指定了用于 HTTP 基本和摘要模式授权的安全区名。<form-login-config> 子元素指定了用表单登录的登录页面的错误页面。如果 <auth-method> 值不是FORM
,那么 form-login-config
及其子元素将被忽略。
/restricted
路径下的任何 URL 都要求 AuthorizedUser
角色。这里不要求传输保证,用于获取用户标识符的验证方式是基本(BASIC)HTTP 验证模式。
例 2.6. web.xml 描述符文件的片段
<web-app> <security-constraint> <web-resource-collection> <web-resource-name>Secure Content</web-resource-name> <url-pattern>/restricted/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>AuthorizedUser</role-name> </auth-constraint> <user-data-constraint> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <!-- ... --> <login-config> <auth-method>BASIC</auth-method> <realm-name>The Restricted Zone</realm-name> </login-config> <!-- ... --> <security-role> <description>The role required to access restricted content </description> <role-name>AuthorizedUser</role-name> </security-role> </web-app>
2.1.8. 启用基于表单的验证
web.xml
的 <login-config> 元素里包含 <auth-method>FORM</auth-method>
来实现的。登录和错误页面也在 <login-config> 里定义:
<login-config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page>/login.html</form-login-page> <form-error-page>/error.html</form-error-page> </form-login-config> </login-config>
FormAuthenticator
把用户引到合适的页面。JBoss EAP 维护了一个会话池,所以并不需要为每个请求准备验证信息。当 FormAuthenticator
接收到一个请求时,它会向 org.apache.catalina.session.Manager
查询现有的会话。如果没有会话存在,新的会话将被创建。FormAuthenticator
然后再检验这个会话的凭证。
注意
/dev/urandom
(Linux) 获取并用 MD5 进行哈希加密的。对 Sesion ID 生成进行检查可以确保 ID 的唯一性。
JSESSIONID
。它的值是 Session ID 的十六进制字符串。这个 cookie 被配置成非持久性的。这意味着当浏览器退出时它不能在客户端删除。在服务器端,会话将在 60 秒不活动后过期,此时会话对象和凭证信息会被删除。
FormAuthenticator
将捕获这个请求,如果有需要则创建一个新的会话,并重定向用户到 login-config
里定义的登录页面。(在之前的代码示例里,登录页面是 login.html
)。然后这个用户在 HTML 表单里输入用户名和密码。用户名和密码将通过 j_security_check
表单动作传入 FormAuthenticator
。
FormAuthenticator
然后根据附加到 Web 应用程序上下文的安全区验证用户名和密码。在 JBoss EAP 里,安全区是 JBossWebRealm
。当验证成功后,FormAuthenticator
从缓存里提取保存的请求并将用户重定向到原始的请求。
注意
/j_security_check
结尾,且至少存在 j_username
和 j_password
参数时才会识别表单验证请求。
2.1.9. 启用声明式安全性
第 3 章 JAAS 简介
3.1. 关于 JAAS
3.2. JAAS 核心类
Subject
(javax.security.auth.Subject
)
Configuration
(javax.security.auth.login.Configuration
)LoginContext
(javax.security.auth.login.LoginContext
)
Principal
(java.security.Principal
)Callback
(javax.security.auth.callback.Callback
)CallbackHandler
(javax.security.auth.callback.CallbackHandler
)LoginModule
(javax.security.auth.spi.LoginModule
)
3.3. Subject 和 Principal 类
Subject
类是 JAAS 里的核心类。Subject
代表单个实体的信息,如某个人或服务。它包含了实体的 principal 、公共凭证和私有凭证。JAAS API 使用现有的 Java 2 java.security.Principal
接口来代表 principal,而它基本上一个类型化名称。
public Set getPrincipals() {...} public Set getPrincipals(Class c) {...}
getPrincipals()
返回所有包含在主题里的主体。getPrincipals(Class c)
只返回那些作为 c
类或其子类实例的主体。如果这个主题没有匹配的主体则返回空集。
java.security.acl.Group
接口是 java.security.Principal
的一个子接口,所以主体集里的实例可能代表其他主体或主体组的逻辑分组。
3.4. 主题(Subject)验证
- 如
LoginModule
配置所要求的,用程序实例化一个LoginContext
并传入登录配置的名称和CallbackHandler
来填充Callback
对象。 LoginContext
咨询Configuration
来加载包括在命名登录配置里的所有LoginModules
。如果不存在这个名称的配置,那么默认会使用other
配置。- 应用程序调用
LoginContext.login
方法。 - 登录模块调用所有加载的
LoginModule
。每个LoginModule
都会试图验证这个主题,它调用相关联的CallbackHandler
上的 handle 犯法来获取验证过程所需的信息。这些信息以Callback
对象队列的方式被传入 handle 方法。成功后,LoginModule
将主题和相关的主体(principal)和凭证关联。 LoginContext
返回验证状态给应用程序。从 login 方法返回则表示成功。如果 login 方法抛出异常则表示失败。- 如果验证成功,应用程序使用
LoginContext.getSubject
方法获取已验证的主题。 - 在主题验证的作用域完成后,所有的主体以及和
login
方法的主题相关的信息都可以通过调用LoginContext.logout
方法进行删除。
LoginContext
类提供了用于验证主题的基本方法以及开发独立于底层验证技术的应用程序的途径。LoginContext
咨询 Configuration
来决定为特定应用程序配置的验证服务。LoginModule
类代表验证服务。因此,你可以插入不同的等录模块到应用程序而无需修改应用程序自身。下面的步骤显示了应用程序验证主题所需的步骤。
CallbackHandler handler = new MyHandler(); LoginContext lc = new LoginContext("some-config", handler); try { lc.login(); Subject subject = lc.getSubject(); } catch(LoginException e) { System.out.println("authentication failed"); e.printStackTrace(); } // Perform work as authenticated Subject // ... // Scope of work complete, logout to remove authentication info try { lc.logout(); } catch(LoginException e) { System.out.println("logout failed"); e.printStackTrace(); } // A sample MyHandler class class MyHandler implements CallbackHandler { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (int i = 0; i < callbacks.length; i++) { if (callbacks[i] instanceof NameCallback) { NameCallback nc = (NameCallback)callbacks[i]; nc.setName(username); } else if (callbacks[i] instanceof PasswordCallback) { PasswordCallback pc = (PasswordCallback)callbacks[i]; pc.setPassword(password); } else { throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback"); } } } }
LoginModule
接口的实现集成验证技术。这允许管理员插入不同的验证技术到应用程序里。你可以将多个 LoginModule
链接在一起来允许多种验证技术来参与验证过程。例如,一个 LoginModule
可以执行基于用户/密码的验证,而另外一个则可以连接硬件设备如智能卡读写器或生物特征识别器。
LoginModule
的生命周期是由客户创建和发行 login 方法所根据的 LoginContext
对象驱动的。这个过程由两阶段组成:
LoginContext
使用其公共的 no-arg 构造器创建每个已配置的LoginModule
。- 每个
LoginModule
都是通过其 initialize 方法来初始化的。Subject
参数需保证是非 null 的。initialize 方法的签名是:public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, Map options)
。 login
被调用来启动验证过程。例如,某个方法实现可能提示用户输入用户名和密码,然后根据存储在命名服务(如 NIS 或 LDAP)里的数据进行检验。其他的实现可能连接智能卡和生物设备,或者简单地从底层操作系统抽取信息。每个LoginModule
对用户标识符的检验会在 JAAS 验证的第一阶段来考虑。login
方法的签名是boolean login() throws LoginException
。LoginException
表示失败。返回值为 true 表示方法调用成功,而 false 表示登录模块应该被忽略。- 如果
LoginException
的总体验证成功,commit
将在每个LoginModule
上调用。如果LoginModule
的第一阶段验证成功,commit 方法将继续第二阶段并将相关的主体、公共凭证和/或私有凭证和关联主题。如果LoginModule
的第一阶段失败,那commit
将删除任何之前保存的验证状态,如用户名或密码。commit
方法的签名是:boolean commit() throws LoginException
。LoginException
的抛出表示完成提交阶段失败。返回值为 true 表示方法调用成功,而 false 表示登录模块应该被忽略。 - 如果
LoginException
的总体验证失败,abort
将在每个LoginModule
上调用。abort
方法删除或销毁任何之前 login 或 initialize 方法创建的验证状态。abort
方法的签名是:boolean abort() throws LoginException
。LoginException
的抛出表示完成abort
阶段失败。返回值为 true 表示方法调用成功,而 false 表示登录模块应该被忽略。 - 要在成功登录后删除验证状态,应用程序将调用
LoginContext
上的logout
。这会导致在每个LoginModule
上调用logout
方法。logout
方法删除原来在commit
阶段和主题相关联的主体和凭证。凭证应该在删除时被销毁。logout
方法的签名是:boolean logout() throws LoginException
。LoginException
的抛出表示完成登出阶段失败。返回值为 true 表示方法调用成功,而 false 表示登录模块应该被忽略。
LoginModule
必须和用户进行通讯来获取验证信息时,它使用 CallbackHandler
对象。应用程序实现 CallbackHandler 接口并将其传入 LoginContext
,这会直接发送验证信息到底层的等录模块。
CallbackHandler
来获取用户的输入,如密码或智能卡 PIN,并提供信息给用户,如状态信息。通过允许应用程序指定 CallbackHandler
,底层的 LoginModule
保持对应用程序和用户交互的独立。例如,GUI 应用程序的 CallbackHandler
实现可能显示一个窗口来让用户输入。另一方面,非 GUI 的应用程序可能 CallbackHandler
简单地使用应用服务器的 API 来获取凭证信息。 CallbackHandler 接口有一个方法需要被实现:
void handle(Callback[] callbacks) throws java.io.IOException, UnsupportedCallbackException;
Callback
接口是我们最后将了解的验证类。它是为几个默认实现提供的一个标记接口,其中包括 NameCallback
和在以前示例里使用的 PasswordCallback
。LoginModule
使用 Callback
来请求验证机制所需的信息。在验证的登录阶段,LoginModule
将一个 Callback
队列直接传入 CallbackHandler.handle
方法。如果 callbackhandler
无法理解如何使用传递到 handle 方法的 Callback
,它会抛出 UnsupportedCallbackException
来中止 login 的调用。
部分 II. 保证平台的安全
第 4 章 安全子系统
4.1. 关于安全子系统
如果 Deep Copy 模式被禁用(默认),复制安全数据结构会产生一个对原始结构的引用,而不是复制整个数据结构。这个行为效率更高,但在具有相同标识符的多个线程通过冲刷或登出操作清除主题时容易受数据损坏的影响。
你可以设置系统范围的安全属性,它们应用在 java.security.Security
类。
安全域(Security Domain)是一系列 Java 验证和授权服务(Java Authentication and Authorization Service,JAAS)的声明式安全配置,一个或多个应用程序用它来控制验证、授权、审计和映射。有三个默认的安全域:jboss-ejb-policy
、jboss-web-policy
和 other
。你也可以按照应用程序的需要创建安全域。
4.2. 关于安全子系统的结构
例 4.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>
元素。
4.3. 配置安全子系统
4.3.1. 配置安全子系统
- <security-management>
- 这部分内容覆盖了安全子系统的高层行为。每个设置都是可选的。除了 Deep Copy 模式,须该这些设置的任何一个都是不寻常的。
选项 描述 deep-copy-subject-mode 指定是否复制或链接安全令牌以用于额外的线程安全。authentication-manager-class-name 指定一个要使用的其他的 AuthenticationManager 实现的类名。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 类上设置的属性的名字和值。
4.3.2. 安全管理
4.3.2.1. 关于 Deep Copy Subject 模式
4.3.2.2. 启用 Deep Copy Subject 模式
过程 4.1. 通过管理控制台启用 Deep Copy 安全模式
登录到管理控制台。
管理控制台通常可通过类似 http://127.0.0.1:9990/ 的 URL 进行访问,请根据需要调整。受管域:选择合适的配置集。
在受管域里,安全子系统是针对每个配置集进行配置的,而且你可以在每个子系统里独立地启用或禁用 Deep Copy 安全模式。要选择配置集,请点击控制台右上角的 Profiles 标签,然后在左上角的 Profile 选择你要修改的配置集家。打开 Security Subsystem 配置菜单。
展开管理控制台右侧的 Security 菜单,然后点击 Security Subsystem 链接。修改 deep-copy-subject-mode 值。
点击 Edit 按钮。选定 Deep Copy Subjects: 复选框来启用 Deep Copy Subject 模式。
如果你想通过管理 CLI 来启用这个选项,请使用下列命令。
例 4.2. 受管域
/profile=full/subsystem=security:write-attribute(name=deep-copy-subject-mode,value=TRUE)
例 4.3. 独立服务器
/subsystem=security:write-attribute(name=deep-copy-subject-mode,value=TRUE)
4.3.3. 安全域
4.3.3.1. 关于安全域
4.3.3.2. 关于 Picketbox
- 第 5.11.1 节 “关于授权” 和访问控制
- 第 5.14.1 节 “关于安全性映射” 和 principal、角色、属性
第 5 章 PicketLink 身份管理
5.1. 关于安全令牌服务(Security Token Service,STS)
- 请求的类型,如 Issue、Renew 等。
- 令牌的类型。
- 发行的令牌的生命周期。
- 关于请求这个令牌的服务提供者的信息。
- 用来加密生成的令牌的信息。
RequestSecurityToken
元素里。这个示例请求包含两个其他的 WS-Trust 元素:RequestType
,它指定这个请求是一个 Issue 请求,而 TokenType
则指定要发出的令牌的类型。
例 5.1. WS-Trust 安全令牌请求消息
<S11:Envelope xmlns:S11=".." xmlns:wsu=".." xmlns:wst=".."> <S11:Header> ... </S11:Header> <S11:Body wsu:Id="body"> <wst:RequestSecurityToken Context="context"> <wst:TokenType>http://www.tokens.org/SpecialToken</wst:TokenType> <wst:RequestType> http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue </wst:RequestType> </wst:RequestSecurityToken> </S11:Body> </S11:Envelope>
例 5.2. 安全令牌响应消息
<wst:RequestSecurityTokenResponse Context="context" xmlns:wst=".." xmlns:wsu=".."> <wst:TokenType>http://www.tokens.org/SpecialToken</wst:TokenType> <wst:RequestedSecurityToken> <token:SpecialToken xmlns:token="..."> ARhjefhE2FEjneovi&@FHfeoveq3 </token:SpecialToken> </wst:RequestedSecurityToken> <wst:Lifetime> <wsu:Created>...</wsu:Created> <wsu:Expires>...</wsu:Expires> </wst:Lifetime> </wst:RequestSecurityTokenResponse>
TokenType
元素指定发出的令牌的类型,而 RequestedSecurityToken
元素包含令牌自身。令牌的格式依赖于令牌的类型。Lifetime
元素指定令牌何时创建和过期。
下面是安全令牌请求被处理的步骤:
- 客户发送一个安全令牌请求到
PicketLinkSTS
。
PicketLinkSTS
解析请求消息,生成 JAXB 对象模型。
PicketLinkSTS
读取配置文件并在需要时创建STSConfiguration
对象。然后它会从配置里获得WSTrustRequestHandler
的引用并将请求处理委托给处理程序实例。
- 请求处理程序在需要时(例如,当请求没有指定令牌的生命周期值)使用
STSConfiguration
来设置默认的值。
WSTrustRequestHandler
创建了WSTrustRequestContext
,设置JAXB
请求对象和从PicketLinkSTS
接收到的调用者主体。
WSTrustRequestHandler
使用STSConfiguration
来获取必须用来处理基于被请求的令牌的类型的SecurityTokenProvider
。然后,它再调用提供者,将构建的WSTrustRequestContext
作为参数传入。
SecurityTokenProvider
实例处理令牌请求并在请求上下文里存储发出的令牌。
WSTrustRequestHandler
从上下文获取令牌,如有需要则将其加密,然后构建包含安全令牌的 WS-Trust 响应对象。
PicketLinkSTS
决定请求处理程序生成的响应并将其返回给客户。
5.2. 配置 PicketLink STS
picketlink-sts.xml
文件里指定。下面是可以在 picketlink-sts.xml
文件里进行配置的元素。
注意
PicketLinkSTS
:这是根元素。它定义允许 STS 管理者设置下列值的属性:STSName
:代表安全令牌服务名称的字符串。如果没有指定,默认值PicketLinkSTS
将被使用。TokenTimeout
:以秒为单位的令牌生命周期。如果没有指定,默认值3600(1小时)将被使用。EncryptToken
:布尔值,指定发出的令牌是否加密。默认值为 false。
KeyProvider
:这个元素及其子元素配置 PicketLink STS 用来签注和加密令牌的密钥库。密钥库位置、密码和签注(私有密钥)别名和密码等属性都可以在这个部分进行配置。RequestHandler
:这个元素指定要使用的WSTrustRequestHandler
实现的权限定名。如果没有指定,默认值org.picketlink.identity.federation.core.wstrust.StandardRequestHandler
将被使用。SecurityTokenProvider
:这个部分指定必需用来处理每种安全令牌的SecurityTokenProvider
实现。在这个例子里,我们有两个提供者 - 一个处理类型为SpecialToken
的令牌而另外一个处理类型为StandardToken
的令牌。WSTrustRequestHandler
调用STSConfiguration
的getProviderForTokenType
(String type) 方法来获得对合适的SecurityTokenProvider
的引用。TokenTimeout
:当在 WS-Trust 请求里没有指定生命周期时,WSTrustRequestHandler
使用它。它创建一个以当前时间为创建时间且在指定的时间后过期的 Lifetime 实例。ServiceProviders
:这个部分指定必须用于每个服务提供者(要求安全令牌的 Web 服务)的令牌类型。当 WS-Trust 请求没有包含令牌类型时,WSTrustRequestHandler
必须使用服务提供者端点来确定要发出的令牌的类型。EncryptToken
:WSTrustRequestHandler
用它来决定发出的令牌是否必须加密。如果为 true,服务提供者的公共密钥证书(PKC)将被用来加密这个令牌。
例 5.3. PicketLink STS 配置
<PicketLinkSTS xmlns="urn:picketlink:identity-federation:config:1.0" STSName="Test STS" TokenTimeout="7200" EncryptToken="true"> <KeyProvider ClassName="org.picketlink.identity.federation.bindings.tomcat.KeyStoreKeyManager"> <Auth Key="KeyStoreURL" Value="keystore/sts_keystore.jks"/> <Auth Key="KeyStorePass" Value="testpass"/> <Auth Key="SigningKeyAlias" Value="sts"/> <Auth Key="SigningKeyPass" Value="keypass"/> <ValidatingAlias Key="http://services.testcorp.org/provider1" Value="service1"/> <ValidatingAlias Key="http://services.testcorp.org/provider2" Value="service2"/> </KeyProvider> <RequestHandler>org.picketlink.identity.federation.core.wstrust.StandardRequestHandler</RequestHandler> <TokenProviders> <TokenProvider ProviderClass="org.picketlink.test.identity.federation.bindings.wstrust.SpecialTokenProvider" TokenType="http://www.tokens.org/SpecialToken"/> <TokenProvider ProviderClass="org.picketlink.identity.federation.api.wstrust.plugins.saml.SAML20TokenProvider" TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"/> </TokenProviders> <ServiceProviders> <ServiceProvider Endpoint="http://services.testcorp.org/provider1" TokenType="http://www.tokens.org/SpecialToken" TruststoreAlias="service1"/> <ServiceProvider Endpoint="http://services.testcorp.org/provider2" TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" TruststoreAlias="service2"/> </ServiceProviders> </PicketLinkSTS>
5.3. 关于 PicketLink STS 登录模块
下面是不同类型的 STS 登录模块。
STSIssuingLoginModule
- 调用配置的 STS 并请求安全令牌。成功后收到
RequestedSecurityToken
,它将标记验证为成功。 - 对 STS 的调用通常需要验证。这个验证模块使用来自下列来源之一的凭证:
- 如果
useOptionsCredentials
模块选项被设置为true
,就是它的属性文件。 - 如果
password-stacking
模块选项被设置为useFirstPass
,则是之前的登录模块凭证。 - 来自配置的
CallbackHandler
(通过提供名称和密码的回调方法)。
- 在成功验证后,如果未发现具有相同 Assertion 的凭证时,
SamlCredential
将插入主题的公共凭证。
STSValidatingLoginModule
- 调用配置的 STS 并检验可用的安全令牌。
- 对 STS 的调用通常需要验证。这个验证模块使用来自下列来源之一的凭证:
- 如果
useOptionsCredentials
模块选项被设置为true
,就是它的属性文件。 - 如果
password-stacking
模块选项被设置为useFirstPass
,则是之前的登录模块凭证。 - 来自配置的
CallbackHandler
(通过提供名称和密码的回调方法)。
- 在成功验证后,如果未发现具有相同 Assertion 的凭证时,SamlCredential 将插入主题的公共凭证。
SAML2STSLoginModule
- 这个登录模块提供一个
ObjectCallback
到配置的CallbackHandler
,并期望返回SamlCredential
对象。Assertion 根据已配置的 STS 来进行校验。 - 如果用户 ID 和 SAML 令牌是被共享的,当位于另外一个已经成功验证的登录模块之上时,这个登录模块将忽略检验。
- 在成功验证后,
SamlCredential
里分别设置为用户的 ID 和角色的NameID
和多重值的角色属性将被检查。
SAML2LoginModule
- 这个登录模块和其他组建一起用于 SAML 验证,其自身不执行验证。
SPRedirectFormAuthenticator
将这个登录模块用在 SAML V2 HTTP 重定向配置集的 PicketLink 实现里。- Tomcat authenticator valve 通过重定向到标识符提供者并获取 SAML 判断来执行验证。
- 这个等录模块被用来传递用户 ID 和角色到 JAAS 主题里填充的 JBoss 安全框架。
5.4. 配置 STSIssuingLoginModule
STSIssuingLoginModule
通过令牌根据 STS 来验证用户名和密码。
例 5.4. 配置 STSIssuingLoginModule
<application-policy name="saml-issue-token"> <authentication> <login-module code="org.picketlink.identity.federation.core.wstrust.auth.STSIssuingLoginModule" flag="required"> <module-option name="configFile">./picketlink-sts-client.properties</module-option> <module-option name="endpointURI">http://security_saml/endpoint</module-option> </login-module> </authentication> <mapping> <mapping-module code="org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSPrincipalMappingProvider" type="principal" /> <mapping-module code="org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSGroupMappingProvider" type="role" /> </mapping> </application-policy>
- 修改它们声明的安全域
- 指定 Principal 映射提供者
- 指定 RoleGroup 映射提供者
5.5. 配置 STSValidatingLoginModule
例 5.5. 配置 STSValidatingLoginModule
<application-policy name="saml-validate-token"> <authentication> <login-module code="org.picketlink.identity.federation.core.wstrust.auth.STSValidatingLoginModule" flag="required"> <module-option name="configFile">./picketlink-sts-client.properties</module-option> <module-option name="endpointURI">http://security_saml/endpoint</module-option> </login-module> </authentication> <mapping> <mapping-module code="org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSPrincipalMappingProvider" type="principal" /> <mapping-module code="org.picketlink.identity.federation.bindings.jboss.auth.mapping.STSGroupMappingProvider" type="role" /> </mapping> </application-policy>
5.6. 基于 SAML Web 浏览器的 SSO
5.6.1. 关于基于 SAML 的 SSO
5.6.2. 使用 HTTP/Redirect 绑定设置基于 SAML v2 的 Web SSO
- 标识符提供者:标识符提供者是负责验证终端用户并以委托方式为合作伙伴评估该用户的标识符的授权实体。
- 服务提供者:服务提供者依赖于标识符提供者并通过电子用户凭证来评估用户的信息,它根据用户凭证评估的信息集合来管理访问控制和传播。
5.6.3. 配置标识符提供者
过程 5.1. 配置标识符提供者(IDP)
为 IDP 配置 web 应用程序的安全性
将 Web 应用程序配置为标识符提供者。注意
我们推荐使用基于 FORM 的 web 应用程序安全性,因为它可让你定制登录页面。下面是一个web.xml
配置的例子例 5.6. IDP 的 web.xml 配置
<display-name>IDP</display-name> <description>IDP</description> <!-- Define a security constraint that gives unlimited access to images --> <security-constraint> <web-resource-collection> <web-resource-name>Images</web-resource-name> <url-pattern>/images/*</url-pattern> </web-resource-collection> </security-constraint> <!-- Define a Security Constraint on this Application --> <security-constraint> <web-resource-collection> <web-resource-name>IDP</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>FORM</auth-method> <realm-name>IDP Application</realm-name> <form-login-config> <form-login-page>/jsp/login.jsp</form-login-page> <form-error-page>/jsp/loginerror.jsp</form-error-page> </form-login-config> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description> The role that is required to log in to the IDP Application </description> <role-name>manager</role-name> </security-role> </web-app>
配置 IDP Valve
在 IDP Web 程序里的 WEB-INF 目录里创建一个context.xml
文件来配置 IDP Valve。下面是一个context.xml
文件的例子。例 5.7. IDP Valve 的 context.xml 文件配置
<context> <Valve className="org.picketlink.identity.federation.bindings.tomcat.idp.IDPWebBrowserSSOValve"/> </context>
配置 PicketLink 文件(picketlink.xml)
配置 IDP Web 程序的 WEB-INF 目录里的picketlink.xml
。在这个配置文件里,你将为服务提供者和 IDP 提供转出 SAML2 评估里的 URL。下面是一个picketlink.xml
文件的例子。例 5.8. picketlink-idfed.xml 配置
<PicketLink xmlns="urn:picketlink:identity-federation:config:2.1"> <PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:2.1"> <IdentityURL>http://localhost:8080/idp/</IdentityURL> </PicketLinkIDP> <Handlers xmlns="urn:picketlink:identity-federation:handler:config:2.1"> <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2IssuerTrustHandler" /> <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler" /> <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler" /> <Handler class="org.picketlink.identity.federation.web.handlers.saml2.RolesGenerationHandler" /> </Handlers> </PicketLink>
5.6.4. 配置服务提供者
过程 5.2. 配置服务提供者
为 SP 配置 Web 应用程序的安全性
要配置为 SP 的 Web 应用程序应该在 web.xml 文件里启用基于 FORM 的安全性。例 5.9. SP 的 web.xml 配置
<display-name>IDP</display-name> <description>IDP</description> <!-- Define a security constraint that gives unlimited access to images --> <security-constraint> <web-resource-collection> <web-resource-name>Images</web-resource-name> <url-pattern>/images/*</url-pattern> </web-resource-collection> </security-constraint> <!-- Define a Security Constraint on this Application --> <security-constraint> <web-resource-collection> <web-resource-name>IDP</web-resource-name> <url-pattern>/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>manager</role-name> </auth-constraint> </security-constraint> <!-- Define the Login Configuration for this Application --> <login-config> <auth-method>FORM</auth-method> <realm-name>IDP Application</realm-name> <form-login-config> <form-login-page>/jsp/login.jsp</form-login-page> <form-error-page>/jsp/loginerror.jsp</form-error-page> </form-login-config> </login-config> <!-- Security roles referenced by this web application --> <security-role> <description> The role that is required to log in to the IDP Application </description> <role-name>manager</role-name> </security-role> </web-app>
配置 SP Valve
要配置 SP 的 Valve,请在 SP Web 应用程序里创建一个context.xml
文件。例 5.10. IDP Valve 的 context.xml 文件配置
<Context> <Valve className="org.jboss.identity.federation.bindings.tomcat.sp.SPRedirectSignatureFormAuthenticator" /> </Context>
配置 PicketLink Federation 的配置文件(picketlink-idfed.xml)
配置 IDP Web 程序的 WEB-INF 目录里的picketlink-idfed.xml
。在这个配置文件里,你将为服务提供者和 IDP 提供转出 SAML2 评估里添加为发行者的 URL。下面是一个picketlink-idfed.xml
文件的例子。例 5.11. picketlink-idfed.xml 配置
<PicketLinkIDP xmlns="urn:picketlink:identity-federation:config:1.0" > <IdentityURL>http://localhost:8080/idp/</IdentityURL> </PicketLinkIDP
配置 PicketLink Federation Handlers 文件(
picketlink-handlers.xml
)配置 SP web 应用程序的 WEB-INF 里的picketlink-handlers.xml
。WEB-INF of your SP web application.例 5.12. 配置 picketlink-handlers.xml
<Handlers xmlns="urn:picketlink:identity-federation:handler:config:1.0"> <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2LogOutHandler"/> <Handler class="org.picketlink.identity.federation.web.handlers.saml2.SAML2AuthenticationHandler"/> </Handlers>
注意
请保留处理程序列出的顺序。
5.6.5. 用 HTTP/POST 绑定设置基于 SAML v2 的 Web SSO
过程 5.3. 用 HTTP/POST 绑定设置基于 SAML v2 的 Web SSO
配置标识符提供者(IDP)。
配置 HTTP/POST 绑定的 IDP 和 HTTP/Redirect 绑定相同。关于配置 IDP 的更多信息,请参考 第 5.6.2 节 “使用 HTTP/Redirect 绑定设置基于 SAML v2 的 Web SSO”。配置服务提供者(Service Provider,SP)
注意
配置 HTTP/POST 绑定的 IDP 和 HTTP/Redirect 绑定相同,除了context.xml
文件里的一个变化。下面是一个 IDP Valve 的context.xml
文件示例。例 5.13. IDP Valve 的 context.xml 文件
<Context> <Valve className="org.picketlink.identity.federation.bindings.tomcat.sp.SPPostFormAuthenticator" /> </Context>
关于配置 SP 的更多信息,请参考 第 5.6.4 节 “配置服务提供者”。
5.7. 配置 SAML 的全局格式配置集
注意
过程 5.4. 配置全局格式(Global Logout)
配置 picketlink-handlers.xml
在 picketlink-handlers.xml 里添加SAML2LogOutHandler
。配置服务提供者的网页
在服务提供者的网页的结尾的链接上附加GLO=true
。例 5.14. 链接至全局格式
<a href="?GLO=true">Click to Globally LogOut</a>
5.8. Kerberos 和 SPNEGO 的集成
5.8.1. 关于 Kerberos 和 SPNEGO 的集成
在典型的设置里,用户会登录到活动目录域管理的桌面。然后用户使用 Web 浏览器(Firefox 或 IE)来访问使用了 EAP 上的 JBoss Negotiation 的 web 程序。Web 浏览器将桌面登录信息传输到 Web 应用程序里。JBoss EAP 使用背景 GSS 消息和活动目录或 kerberos 服务器来验证这个用户。这让用户可以实现对 Web 应用程序的无缝 SSO。
5.8.2. 使用 SPNEGO 的桌面 SSO
- 安全域
- 系统属性
- Web 应用程序
过程 5.5. 配置使用 SPNEGO 的桌面 SSO
配置安全域
配置安全域来代表服务器的标识符并为 Web 应用程序设置安全性。例 5.15. 安全域配置
<security-domains> <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> <security-domain name="SPNEGO" cache-type="default"> <authentication> <login-module code="SPNEGO" flag="requisite"> <module-option name="password-stacking" value="useFirstPass"/> <module-option name="serverSecurityDomain" value="host"/> </login-module> <!-- Login Module For Roles Search --> </security-domain>
设置系统属性
如果需要,系统殊性可以在域模型里进行设置。例 5.16. 配置系统属性
<system-properties> <property name="java.security.krb5.kdc" value="mykdc.mydomain"/> <property name="java.security.krb5.realm" value="MY_REALM"/> </system-properties>
配置 Web 应用程序
覆盖这个验证器是不可能的,但你可以在 jboss-web.xml 里添加NegotiationAuthenticator
来配置 web 应用程序。注意
这个 Valve 要求在 web.xml 里定义security-constraint
和login-config
,因为它们用于决定哪些资源被保护。然而,这个验证器会覆盖所选的auth-method
。例 5.17. 配置 Web 应用程序
<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 2.4//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_4_0.dtd"> <jboss-web> <security-domain>java:/jaas/SPNEGO</security-domain> <valve> <class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name> </valve> </jboss-web>
这个 Web 应用程序也要求在META-INF/MANIFEST.MF
定义依赖关系,以便定位 JBoss Negotiation 类。例 5.18. 在
META-INF/MANIFEST.MF
里定义依赖关系Manifest-Version: 1.0 Build-Jdk: 1.6.0_24 Dependencies: org.jboss.security.negotiation
5.8.3. 为 Microsoft Windows Domain 配置 JBoss Negotiation
{hostname}
,安全区被称为 {realm}
,域被称为 {domain}
,而运行 JBoss EAP 实例的服务器被称为 {machine_name}
。
过程 5.6. 为 Microsoft Windows Domain 配置 JBoss Negotiation
清除现有的 Service Principal Mapping
在 Microsoft Windows 网络里,某些映射是自动创建的。删除这些自动创建的映射以使得服务器的标识符可以正确映射到用于协商的服务主体。这些映射让客户端的 Web 浏览器信任服务器并尝试 SPNEGO。客户端将用域控制器检验映射是否是HTTP{hostname}
格式。下面是删除现有映射的步骤:- 用这个命令来列出注册了域的映射:
setspn -L {machine_name}
。 - 用下列命令来删除现有的映射:
setspn -D HTTP/{hostname} {machine_name}
andsetspn -D host/{hostname} {machine_name}
。
- 创建一个主机用户帐号。
注意
确保主机用户名和{machine_name}
不一样。在本节后面的内容里,主机用户名被称为{user_name}
。 定义
{user_name}
和{hostname}
之间的映射。- 运行下列命令来配置 Service Principal Mapping:
ktpass -princ HTTP/{hostname}@{realm} -pass * -mapuser {domain}\{user_name}
。 - 提示时输入用户的密码。
注意
重置用户密码,这是导出 keytab 的一个前提条件。 - 运行下列命令
setspn -L {user_name}
来检验这个映射。
导出用户的 keytab 到安装了 JBoss EAP 的服务器上。
运行下列命令来导出 keytab:ktab -k service.keytab -a HTTP/{hostname}@{realm}
。注意
这个命令导出 HTTP/{hostname} 主体的票据到在 JBoss 用来配置主机安全域的 keytabservice.keytab
。- 在安全域里定义主体:
<module-option name="principal">HTTP/{hostname}@{realm}</module-option>
5.9. 验证
5.9.1. 关于验证
5.9.2. 配置安全域的验证
过程 5.7. 为安全域设置验证
打开安全域的详细视图。
点击管理控制台由上角的 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 里的 Edit 按钮修改它的 Code 或Flags。请确保选择了 Attributes 标签页。可选的:添加或删除模块选项。
如果你需要在模块里添加选项,请点击 Login Modules 列表里的条目,并在 Details 页面里选择 Module Options 标签页。点击 Add 按钮,并提供这个选项的键和值。你可以用 Remove 按钮来删除选项。
你的验证模块已添加至安全域,且马上可为使用安全域的应用程序所用。
jboss.security.security_domain
模块选项
在默认情况下,安全域里定义的每个登录模块都会自动添加一个 jboss.security.security_domain
模块选项。这个选项会给检查是否只定义了已知选项的登录模块带来问题。IBM Kerberos 登录模块 com.ibm.security.auth.module.Krb5LoginModule
就是其中之一。
true
来禁用添加这个模块选项的行为。请添加下列内容到你的启动参数里。
-Djboss.security.disable.secdomain.option=true
5.10. Java 容器验证 SPI(JASPI)
5.10.1. 关于 Java 容器验证 SPI(JASPI)的安全性
5.10.2. 配置 Java 容器验证 SPI(JASPI)的安全性
<authentication-jaspi>
元素到你的安全域里。其配置和标准的验证模块类似,但登录模块元素包含在 <login-module-stack>
元素里。它的配置的结构是:
例 5.19. 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。
5.11. 授权
5.11.1. 关于授权
5.11.2. 配置安全域里的授权
过程 5.8. 在安全域里设置授权
打开安全域的详细视图。
点击管理控制台由上角的 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。关于更消息的信息,请参考这个文档。
标签 详情 required 登录模块是授权成功所必需的。如果成功或失败,授权都仍会继续处理登录模块列表。requisite 登录模块是授权成功所必需的。如果成功,授权将继续处理登录模块列表。如果失败,控制权马上返回给应用程序(授权不会继续处理登录模块列表)。sufficient 登录模块不是授权成功所必需的。如果成功,控制权马上返回给应用程序(授权不会继续处理登录模块列表)。如果失败,授权将继续处理登录模块列表。optional 登录模块不是授权成功所必需的。如果成功或失败,授权都仍会继续处理登录模块列表。在你添加了模块时,你可以通过屏幕上的 Details 里的 Edit 按钮修改它的 Code 或Flags。请确保选择了 Attributes 标签页。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Login Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,点击它的键来进行修改。你可以使用 Remove 按钮来删除选项。
你的授权模块已添加至安全域,且马上可为使用安全域的应用程序所用。
5.12. Java 容器授权合约(JACC)
5.12.1. 关于 Java 容器授权合约(JACC)
5.12.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 里有相关的文档。
例 5.20. 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。
例 5.21. EJB 里的安全域声明示例
<security> <ejb-name>*</ejb-name> <security-domain>myDomain</security-domain> <run-as-principal>myPrincipal</run-as-principal> </security>
5.12.3. 使用 XACML 的细颗粒度授权
5.12.3.1. 关于细颗粒度授权和 XACML
- DENY - 访问被批准。
- DENY - 访问被拒绝。
- INDETERMINATE - PDP 里有一个错误。
- NOTAPPLICABLE - 请求里缺乏某个属性或者没有匹配的策略。
- Oasis XACML v2.0 库
- 基于 JAXB v2.0 的对象模型
- 用于存储/读取 XACML 策略和属性的 ExistDB 集成
5.12.3.2. 为细颗粒度授权配置 XACML
过程 5.9. 配置 XACML
- 下载库(单个 JAR 文件)。
为 XACML 创建一个或多个策略文件
- 在
WEB-INF/classes
目录下创建一个policies
目录来保存你的策略。 - 在
WEB-INF/classes
目录下创建一个policyConfig.xml
文件。下面是可以定义的两种策略集:- 角色权限策略集(Role Permission Policy Set,RPS)
- 权限策略集(Permission Policy Sets,PPS)
例 5.22. 角色权限策略集(Role Permission Policy Set,RPS)
雇员<PolicySet xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" PolicySetId="RPS:employee:role" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides"> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">employee</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> </SubjectMatch> </Subject> </Subjects> </Target> <!-- Use permissions associated with the employee role --> <PolicySetIdReference>PPS:employee:role</PolicySetIdReference> </PolicySet>
管理器<PolicySet xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" PolicySetId="RPS:manager:role" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides"> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">manager</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI"/> </SubjectMatch> </Subject> </Subjects> </Target> <!-- Use permissions associated with the manager role --> <PolicySetIdReference>PPS:manager:role</PolicySetIdReference> </PolicySet>
例 5.23. 权限策略集(Permission Policy Sets,PPS)
雇员<PolicySet xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" PolicySetId="PPS:employee:role" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides"> <Target /> <!-- Permissions specifically for the employee role --> <Policy PolicyId="Permissions:specifically:for:the:employee:role" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides"> <Target /> <!-- Permission to create a purchase order --> <Rule RuleId="Permission:to:create:a:purchase:order" Effect="Permit"> <Target> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">purchase order </AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" /> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create</AttributeValue> <ActionAttributeDesignator AttributeId="urn:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" /> </ActionMatch> </Action> </Actions> </Target> </Rule> </Policy> <!-- HasPrivilegesOfRole Policy for employee role --> <Policy PolicyId="Permission:to:have:employee:role:permissions" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides"> <Target /> <!-- Permission to have employee role permissions --> <Rule RuleId="Permission:to:have:employee:permissions" Effect="Permit"> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">employee</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI" /> </Apply> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">urn:oasis:names:tc:xacml:2.0:actions:hasPrivilegesOfRole </AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#anyURI" /> </Apply> </Apply> </Condition> </Rule> </Policy> </PolicySet>
管理器<PolicySet xmlns="urn:oasis:names:tc:xacml:2.0:policy:schema:os" PolicySetId="PPS:manager:role" PolicyCombiningAlgId="urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:permit-overrides"> <Target /> <!-- Permissions specifically for the manager role --> <Policy PolicyId="Permissions:specifically:for:the:manager:role" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides"> <Target /> <!-- Permission to sign a purchase order --> <Rule RuleId="Permission:to:sign:a:purchase:order" Effect="Permit"> <Target> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">purchase order </AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string" /> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">sign</AttributeValue> <ActionAttributeDesignator AttributeId="urn:action-id" DataType="http://www.w3.org/2001/XMLSchema#string" /> </ActionMatch> </Action> </Actions> </Target> </Rule> </Policy> <!-- HasPrivilegesOfRole Policy for manager role --> <Policy PolicyId="Permission:to:have:manager:role:permissions" RuleCombiningAlgId="urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:permit-overrides"> <Target /> <!-- Permission to have manager role permissions --> <Rule RuleId="Permission:to:have:manager:permissions" Effect="Permit"> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">manager</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI" /> </Apply> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:anyURI-is-in"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">urn:oasis:names:tc:xacml:2.0:actions:hasPrivilegesOfRole </AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#anyURI" /> </Apply> </Apply> </Condition> </Rule> </Policy> <!-- Include permissions associated with employee role --> <PolicySetIdReference>PPS:employee:role</PolicySetIdReference> </PolicySet>
为 XACML 引擎创建一个配置文件。
配置文件将被创建以配置定位器并指定策略保存的目录。例 5.24. 配置文件
只指示策略文件目录的配置文件。<ns:jbosspdp xmlns:ns="urn:jboss:xacml:2.0"> <ns:Policies> <ns:PolicySet> <ns:Location>test/policies/rbac/</ns:Location> </ns:PolicySet> </ns:Policies> <ns:Locators> <ns:Locator Name="org.jboss.security.xacml.locators.JBossRBACPolicySetLocator"/> </ns:Locators> </ns:jbosspdp>
定义策略集的配置文件<ns:jbosspdp xmlns:ns="urn:jboss:xacml:2.0"> <ns:Policies> <ns:PolicySet> <ns:Location>test/policies/rbac/employee-PPS-policyset.xml</ns:Location> </ns:PolicySet> <ns:PolicySet> <ns:Location>test/policies/rbac/manager-PPS-policyset.xml</ns:Location> </ns:PolicySet> <ns:PolicySet> <ns:Location>test/policies/rbac/employee-RPS-policyset.xml</ns:Location> </ns:PolicySet> <ns:PolicySet> <ns:Location>test/policies/rbac/manager-RPS-policyset.xml</ns:Location> </ns:PolicySet> </ns:Policies> <ns:Locators> <ns:Locator Name="org.jboss.security.xacml.locators.JBossRBACPolicySetLocator"/> </ns:Locators> </ns:jbosspdp>
- 创建一个策略决策点(Policy Decision Point,PDP)并将其传入配置文件里。
- 在策略强制点(Policy Enforcement Point,PEP)里,创建一个基于上下文的 XACML。将这个 XACML 请求传入 PDP 以获得下列访问决定:
- Permit
- Deny
- Indeterminate
- Not Applicable
例 5.25. 访问决定
许可条件<Request xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:context:schema:os access_control-xacml-2.0-context-schema-os.xsd"> <Subject> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"> <AttributeValue>Anne</AttributeValue> </Attribute> <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI"> <AttributeValue>manager</AttributeValue> </Attribute> </Subject> <Resource> <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI"> <AttributeValue>manager</AttributeValue> </Attribute> </Resource> <Action> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#anyURI"> <AttributeValue>urn:oasis:names:tc:xacml:2.0:actions:hasPrivilegesOfRole</AttributeValue> </Attribute> </Action> </Request>
拒绝权限<Request xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xacml:2.0:context:schema:os access_control-xacml-2.0-context-schema-os.xsd"> <Subject> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"> <AttributeValue>Anne</AttributeValue> </Attribute> <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI"> <AttributeValue>manager</AttributeValue> </Attribute> </Subject> <Resource> <Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:subject:role" DataType="http://www.w3.org/2001/XMLSchema#anyURI"> <AttributeValue>manager</AttributeValue> </Attribute> </Resource> <Action> <Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#anyURI"> <AttributeValue>urn:nobody</AttributeValue> </Attribute> </Action> </Request>
5.13. 安全审计
5.13.1. 关于安全性审计
5.13.2. 配置安全审计
过程 5.10. 在安全域里设置安全审计
打开安全域的详细视图。
点击管理控制台由上角的 Profiles 标签。在独立服务器里,标签页是 Profile。在受管域里,从 Profile 视图左上角的 Profile 选择框里选择要修改的配置集。点击左侧的 Security 并点击展开菜单里的 Security Domains。点击你要编辑的安全域的 View 链接。进入审计子系统配置。
如果还未选择的话,点击视图顶部的 Audit 标签。配置区域分成两部分:Provider Modules 和 Details。提供者模块(Provider Module)是配置的基本单元。安全域可以包含多个提供者模块,每个都包括几个属性和选项。添加一个提供者模块。
点击 Add 按钮来添加一个提供者模块。在 Code 里输入提供者模块的类名。在你添加了模块时,你可以通过屏幕上的 Details 里的 Edit 按钮修改它的 Code。请确保选择了 Attributes 标签页。检验你的模块是否可以运行
审计模块的目的是提供一个在安全子系统里监控事件的途径。这种监控可以通过写入日志文件、电子邮件通知或其他可度量的审计机制来实现。例如,JBoss EAP 6 默认包含了LogAuditProvider
模块。如果按照上面的步骤启用,这个审计模块会将安全通知写入EAP_HOME
目录里的log
子目录下的audit.log
文件里。要检验上面的步骤是否可以在LogAuditProvider
上下文里运行,你可以执行一个可能触发通知的动作并检查审计日志文件。关于安全审计提供者模块的完整列表,请参考 第 A.4 节 “包括的安全审计供应商模块”。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,你可以使用 Remove 按钮来删除它,或者用正确的选项点击 Add 按钮再次添加它。
你的安全审计模块已添加至安全域,且马上可为使用安全域的应用程序所用。
5.14. 安全性映射
5.14.1. 关于安全性映射
5.14.2. 在安全域里配置安全映射
过程 5.11. 在安全域里设置安全映射
打开安全域的详细视图。
点击管理控制台由上角的 Profiles 标签。在独立服务器里,标签页是 Profile。在受管域里,从 Profile 视图左上角的 Profile 选择框里选择要修改的配置集。点击左侧的 Security 并点击展开菜单里的 Security Domains。点击你要编辑的安全域的 View 链接。进入映射子系统配置。
如果还未选择的话,点击视图顶部的 Mapping 标签。配置区域分成两部分:Modules 和 Details。映射模块是配置的基本单元。安全域可以包含多个映射模块,每个都包括几个属性和选项。添加一个模块。
点击 Add 按钮来添加一个安全映射模块。输入模块的相关内容。Code 是模块的类名。Type 字段表示这个模块执行的映射的类型。所允许的值有 principal、role、attribute 和 credential。在你添加了模块时,你可以通过屏幕上的 Details 里的 Edit 按钮修改它的 Code 或Type。请确保选择了 Attributes 标签页。可选的:添加、编辑或删除模块选项。
如果你需要在模块里添加选项,点击 Modules 列表里的条目,并选择 Details 部分的 Module Options 标签页,并提供选项的键和值。要编辑一个已存在的选项,点击 Remove 标签键来删除它,并用新的值再次添加它。你可以使用 Remove 按钮来删除选项。
你的安全映射模块已添加至安全域,且马上可为使用安全域的应用程序所用。
5.15. 在应用程序里使用安全域
要在应用程序里使用安全域,首先你必须通过服务器配置文件或应用程序的描述符文件配置安全域。然后你必须添加必要的注解到使用安全域的 EJB。这个主题涵盖了在应用程序里使用安全域所需的步骤。
过程 5.12. 配置你的应用程序以使用安全域
定义安全域
你可以在服务器的配置文件或应用程序的描述符里定义安全域。在服务器的配置文件里配置安全域
安全域是在服务器配置文件的security
子系统里配置的。如果 JBoss EAP 6 实例运行在受管域里,配置文件应该是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,你可以在红帽的客户门户找到这些例子。
第 6 章 Java 安全性管理者
6.1. 关于 Java 安全性管理者
Java 安全性管理者是一个管理 Java 虚拟机(JVM)sandbox 外部边界的类,它控制代码在 JVM 里执行时如何和外部的资源交互。当 Java 安全性管理者被激活时,Java API 在执行许多有潜在风险的操作之前会检查 Java 安全性管理者以获得批准。
6.2. 关于 Java 安全管理者策略
以不同代码类别表示的一系列权限。Java 安全管理者将应用程序的动作请求和安全策略进行比较。如果某个动作是策略所允许的,那么安全管理者将允许这个动作执行。如果这个动作是策略所不允许的,那么将拒绝这个动作的执行。安全策略可以根据代码的位置或签名来定义权限。
java.security.manager
和 java.security.policy
配置的。
6.3. 在 Java 安全管理者里运行 JBoss EAP 6
domain.sh
或 standalone.sh
脚本。下面的过程会指引你配置实例以在 Java 安全管理者里运行 JBoss EAP。
前提条件
- 在执行下列过程之前,你需要用 JDK 里包含的
policytool
编写一个安全策略。这个过程假定你的策略位于EAP_HOME/bin/server.policy
。 - 在编辑配置文件之前,域或独立服务器必须完全停止。
过程 6.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"
启动域或服务器。
正常地启动域或服务器。
6.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“。
- Permissions
- 赋予代码的权限。许多权限是作为 Java EE 规格的一部分提供的。本文档只涵盖由 JBoss EAP 6 提供的其他权限。
过程 6.2. 设置新的 Java 安全性管理者策略
启动
policytool
.以下列方式之一启动policytool
工具。红帽企业版 Linux
在 GUI 或命令行提示下,运行/usr/bin/policytool
。Microsoft Windows Server
从开始菜单或 Java 安装的bin\
里运行policytool.exe
。在不同系统里,其位置可能会不一样。
创建一个策略。
要创建一个策略,请选择 Add Policy Entry。添加你需要的参数,然后点击 Done。编辑现有的策略
从现有的策略列表里选择策略,并选择 Edit Policy Entry 按钮。然后根据需要编辑相关参数。删除现有的策略。
从现有的策略列表里选择策略,并选择 Remove Policy Entry 按钮。
JBoss EAP 6 专有的权限
- 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)
6.5. 调试安全管理者策略
java.security.debug
选项配置和安全相关的信息的级别。java -Djava.security.debug=help
命令将产生具有完整调试选项的帮助信息。当解决和安全相关的故障而完全不知道原因时,设置调试级别为 all
是很有用的。但对于普通的用途而言,这会产生过多的信息。一般默认的选项是 access:failure
。
过程 6.3. 启用普通调试
这个过程将启用普通级别的和安全相关的调试信息。
在服务器配置文件里添加下列行。- 如果 JBoss EAP 6 实例运行在受管域里,这一行将添加到
bin/domain.conf
()或bin/domain.conf.bat
(Windows)。 - 如果 JBoss EAP 6 实例作为独立服务器运行,这一行将添加到
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"
启用了普通级别的和安全相关的调试信息。
第 7 章 安全区
7.1. 关于安全区
ManagementRealm
存储用于管理 API 的验证信息,它提供管理 CLI 和基于 web 的管理控制台的功能。它也为管理 JBoss EAP 自身提供了一个验证系统。如果你的应用程序需要用用于管理 API 的相同商业规则来验证,你也可以使用ManagementRealm
。ApplicationRealm
存储用于 Web 应用程序和 EJB 的用户、密码和角色信息。
REALM-users.properties
存储用户名和 hashed 密码。REALM-users.properties
存储用户和角色的映射。
domain/configuration/
和 standalone/configuration/
目录里。这些文件由 add-user.sh
或 add-user.bat
同时写入。当你运行这命令时,你的第一个决定是添加新用户到哪个区。
7.2. 添加新的安全区
运行管理 CLI。
运行jboss-cli.sh
或jboss-cli.bat
命令并连接服务器。创建新的安全区。
运行下列命令在域控制器或独立服务器上创建一个名为MyDomainRealm
的安全区。/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)
你的新安全区已被创建了。当你添加用户和角色到这个新的安全区时,信息将被存储在默认安全区外的一个单独的文件里。你可以用自己的应用程序或过程来管理这个新的文件。
7.3. 添加用户到安全区里
运行
add-user.sh
或add-user.bat
命令。打开一个终端并进入EAP_HOME/bin/
目录。如果你运行的是红帽企业版 LInux 或其他类 Unix 系统,请运行add-user.sh
。如果你运行的是 Microsoft Windows 服务器,则请运行add-user.bat
。选择是否添加管理用户或应用程序用户。
对于这个过程,输入b
来添加应用程序用户。选择用户所添加至的安全区。
在默认的情况下,唯一可用的安全区是ApplicationRealm
。如果你已经添加了一个自定义区,你可以输入它的名称。在提示时输入用户名、密码和角色。
在提示时输入想要的用户名、密码和可选角色。输入yes
确认选择或no
取消修改。所作修改将被写入到安全区的每个属性文件里。
第 8 章 加密
8.1. 关于加密
8.2. 关于 SSL 加密
8.3. 对 JBoss EAP 6 Web 服务器实施 SSL 加密
许多 web 应用程序都要求对客户端和服务器间的连接进行 SSL 加密,这也被称为 HTTPS
连接。你可以通过这个过程对服务器或服务器组启用 HTTPS
。
前提条件
- 你需要一系列 SLL 加密密钥和加密证书。你可以从证书签名机构购买或者使用命令行工具来生成。关于使用红帽企业版 Linux 工具来生成加密密钥,请参考 第 8.4 节 “生成 SSL 密钥和证书”。
- 你需要知道你的环境和设置的下列细节:
- 你的证书文件的完整目录名和路径
- 你的加密密钥的密码。
- 你需要运行管理 CLI 并连接到域控制器或独立服务器。
注意
/profile=default
删除。
过程 8.1. 配置 JBoss Web 服务器以使用 HTTPS
添加新的 HTTPS 连接器。
执行下列管理 CLI 命令来修改配置。这会创建一个新的加密连接器,名为HTTPS
。它使用https
模式、https
套接字绑定(默认为8443
端口),且被设置为安全的。例 8.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/
。例 8.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 属性参数的完整列表,请参考 第 8.5 节 “SSL 连接器引用”。部署应用程序。
部署一个使用你已经配置好的配置集的应用程序到服务器组。如果你使用的是独立服务器,将这个应用程序部署至服务器。它的 HTTP 请求将使用新的 SSL 加密的连接。
8.4. 生成 SSL 密钥和证书
前提条件
- 你需要
keytool
工具,任何 JDK 都提供它。红帽企业版 Linux 上的 OpenJDK 将这个命令安装在/usr/bin/keytool
。 - 请理解
keytool
命令的语法和参数。这个过程将使用非常浅显的说明,因为对 SSL 证书或keytool
命令的深入讨论都超出了本文档的范畴。
过程 8.2. 生成 SSL 密钥和证书
用公共和私有密钥生成密钥库。
运行下列命令来当前目录里生成带有别名jboss
的名为server.keystore
的密钥库。keytool -genkeypair -alias jboss -keyalg RSA -keystore server.keystore -storepass mykeystorepass --dname "CN=jsmith,OU=Engineering,O=mycompany.com,L=Raleigh,S=NC,C=US"
下表描述了用于 keytool 命令的参数:参数 描述 -genkeypair
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 服务器通讯。
8.5. SSL 连接器引用
default
配置集的受管域的。按照你的需要修改这个配置集名称(对于受管域),或者忽略命令行的 /profile=default
部分(对于独立服务器)。
表 8.1. SSL 连接器属性
属性 | 描述 | 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 6 的用户的主目录下的
.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 |
用于信任库和密钥库的密码。在下面的例子里,请用自己的密码替换 PASSWORD。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=password,value=PASSWORD) |
protocol |
要使用的 SSL 协议的版本。支持的值包括
SSLv2 、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 |
用于密钥库里的服务器证书的别名。在下面的例子里,请用你的证书别名替换 KEY_ALIAS。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=key-alias,value=KEY_ALIAS) |
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 的证书密码。在下面的例子里,请用自己的掩码密码替换其中的 MASKED_PASSWORD。
|
/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 会话缓存的大小。这个属性仅用于 JSSE 连接器。默认值是
0 ,它表示缓存大小是无限的。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=session-cache-size,value=100) |
session-timeout |
在缓存的 SSLSession 过期前的秒数。这个属性仅适用于 JSSE 连接器。默认值为
86400 秒,也就是 24 小时。
|
/profile=default/subsystem=web/connector=HTTPS/ssl=configuration/:write-attribute(name=session-timeout,value=43200) |
8.6. 兼容 FIPS 140-2 的加密
8.6.1. 关于 FIPS 140-2 兼容性
8.6.2. 兼容 FIPS 140-2 的密码
- 其长度必须至少有 7 个字符。
- 必须包含来自至少三个下列字符类别里的字符:
- ASCII 数字
- 小写的 ASCII 字符
- 大写的 ASCII 字符
- 非字母的 ASCII,和
- 非 ASCII 字符
8.6.3. 在红帽企业版 Linux 6 上启用 SSL 的 FIPS 140-2 加密
前提条件
- 红帽企业版 Linux 6 必须已经配置为 FIPS 140-2 兼容的模式。请参考 https://access.redhat.com/knowledge/solutions/137833。
过程 8.3. 启用 SSL 的 FIPS 140-2 兼容加密
创建数据库
在jboss
用户拥有的一个目录里创建 NSS 数据库。$ mkdir -p /usr/share/jboss-as/nssdb $ chown jboss /usr/share/jboss-as/nssdb $ modutil -create -dbdir /usr/share/jboss-as/nssdb
创建 NSS 配置文件
在/usr/share/jboss-as
目录里创建一个名为nss_pkcsll_fips.cfg
的文本文件,它具有下列内容:name = nss-fips nssLibraryDirectory=/usr/lib64 nssSecmodDirectory=/usr/share/jboss-as/nssdb nssModule = fips
NSS 配置文件必须指定:- 名称
- NSS 库所在的目录,和
- 步骤 1 里创建 NSS 数据库用到的目录。
如果你使用的是红帽企业版 Linux 6 的 64 位版本,请设置nssLibraryDirectory
为/usr/lib
而不是/usr/lib64
。启用 SunPKCS11 供应商
编辑你的 JRE 的java.security
配置文件($JAVA_HOME/jre/lib/security/java.security
)并添加下列行:security.provider.1=sun.security.pkcs11.SunPKCS11 /usr/share/jboss-as/nss_pkcsll_fips.cfg
请注意这一行里指定的配置文件就是我们在步骤 2 里创建的文件。这个文件里的任何其他security.provider.X
行都必须将 X 递增以设置对应供应商的优先级。为 NSS 库启用 FIPS 模式
运行modutil
命令以启用 FIPS 模式:modutil -fips true -dbdir /usr/share/jboss-as/nssdb
请注意这里指定的目录就是我们在步骤 1 里创建的目录。此时你可能遇到一个安全库错误,要求你为某些 NSS 共享对象重新生成库签名。修改 FIPS 令牌的密码
用下列命令在 FIPS 令牌上设置密码。请注意,令牌的名称必须为NSS FIPS 140-2 Certificate DB
。modutil -changepw "
NSS FIPS 140-2 Certificate DB
" -dbdir /usr/share/jboss-as/nssdb用于 FIPS 令牌的密码必须是兼容 FIPS 的密码。使用 NSS 工具创建证书
输入下列命令来用 NSS 工具创建证书。certutil -S -k rsa -n jbossweb -t "u,u,u" -x -s "CN=localhost, OU=MYOU, O=MYORG, L=MYCITY, ST=MYSTATE, C=MY" -d /usr/share/jboss-as/nssdb
配置 HTTPS 连接器使用 PKCS11 密钥库
用 JBoss CLI 工具里的下列命令添加一个 HTTPS 连接器:/subsystem=web/connector=https/:add(socket-binding=https,scheme=https,protocol=HTTP/1.1,secure=true)
然后用下列命令添加 SSL 配置,用兼容 FIPS 的密码(参考步骤 5)替换这里的 PASSWORD。/subsystem=web/connector=https/ssl=configuration:add(name=https,password=PASSWORD,keystore-type=PCKS11, cipher-suite="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_AES_256_CBC_SHA")
检验
运行下列命令检验 JVM 是否可以从 PKCS11 密钥库楼里读取私有密钥:keytool -list -storetype pkcs11
例 8.3. 使用 FIPS 140-2 的 HTTPS 连接器的 XML 配置
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https" secure="true"> <ssl name="https" password="****" cipher-suite="SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA,TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_AES_256_CBC_SHA" keystore-type="PKCS11"/> </connector>
cipher-suite
属性里插入了断行符以便于阅读。
第 9 章 网络安全性
9.1. 保护管理接口
在测试环境里,我们通常在由管理控制台、管理 CLI 和其他 API 实现组成的管理接口上不设置安全层来运行 JBoss EAP 6 。这可以允许快速的开发和配置修改。
9.2. 指定 JBoss EAP 6 使用的网络接口
隔离服务以使它们只被需要它们的客户访问,这样可以增强网络的安全性。JBoss EAP 在其默认配置里包含两个接口,两者都绑定到 IP 地址127.0.0.1
或 localhost
。其中一个被称为 management
,它被管理控制台、CLI 和 API 使用。另外一个被称为 public
,被用来部署应用程序。这些接口并不特殊或有什么含义,只是作为起点来提供。
management
接口默认使用端口 9990 和 9999,而public
接口使用端口 8080 或 8443(如果使用 HTTPS)。
警告
停止 JBoss EAP 6 服务器。
以合适的方式对操作系统发送中断信号来停止 JBoss EAP 6。如果你以前台应用程序的方式运行 JBoss EAP 6,那通常的做法是按 Ctrl+C 键。重启 JBoss EAP 6,指定绑定地址。
使用-b
命令行选项在特定接口上启动 JBoss EAP 6。例 9.1. 指定公共接口。
EAP_HOME/bin/domain.sh -b 10.1.1.1
例 9.2. 指定管理接口。
EAP_HOME/bin/domain.sh -bmanagement=10.1.1.1
例 9.3. 为每个接口指定不同的地址。
EAP_HOME/bin/domain.sh -bmanagement=127.0.0.1 -b 10.1.1.1
例 9.4. 绑定公共接口到所有的网络接口上。
EAP_HOME/bin/domain.sh -b 0.0.0.0
-b
命令行选项在运行时指定 IP 地址,所以我们不推荐这么做。如果确实要这么做,请在编辑 XML 文件前完全停止 JBoss EAP 6。
9.3. 配置和 JBoss EAP 6 一起使用的网络防火墙
多数产品环境都使用防火墙作为总体网络安全策略的一部分。如果你需要多个 EAP 服务器来与其他 EAP 服务器或外部服务(如 Web 服务器或数据库)来通讯,你的防火墙必须考虑这一点。管理良好的防火墙只会打开操作所需的端口,它会限制对某些 IP 地址、子网和网络协议的端口的访问。
前提条件
- 确定你要打开的端口。
- 对防火墙软件的理解是必需的。在红帽企业版 Linux 6 里,这个过程会使用
system-config-firewall
命令。微软的 Windows 服务器包括了内置的防火墙,以及几个可用于任何平台的第三方的防火墙解决方案。
这个过程配置防火墙是基于如下假设的:
- 操作系统为红帽企业版 Linux 6。
- JBoss EAP 6 运行在主机
10.1.1.2
上。或者,EAP 服务器具有自己的防火墙。 - 网络防火墙服务器运行在主机
10.1.1.1
的接口eth0
上,且具有外部的接口eth1
。 - 你想把端口 5445(JMS 使用的端口)上的流量转发到 JBoss EAP 6。网络防火墙应该不允许其他流量通过。
过程 9.1. 管理和 JBoss EAP 6 一起使用的网络防火墙
登录到管理控制台。
登录到管理控制台。在默认情况下,它运行在 http://localhost:9990/console/ 上。确定套接字绑定组使用的套接字绑定。
点击管理控制台右上方的 Profiles 标签。在屏幕的左侧会显示一系列菜单。菜单底部是 General Configuration。点击它下面的 Socket Binding。Socket Binding Declarations 屏幕将会出现,一开始它会显示standard-sockets
组。你可以从右侧的复合框里来选择不同的组。注意
如果你使用的是独立服务器,它只有一个套接字绑定组。套接字名称和端口将会出现,每页有 8 个值。你可以使用表下面的箭头来进行浏览。确定你要打开的端口。
根据特定端口的功能以及系统环境的要求,你可能需要在防火墙上打开某些端口。配置防火墙将通讯转发到 JBoss EAP 6。
执行这些步骤来配置网络防火墙以允许指定端口上的通讯。- 登录到防火墙主机并以根用户身份打开命令行提示。
- 执行
system-config-firewall
来启动防火墙配置工具。GUI 或命令行工具根据你登录到防火墙系统的方式启动。这个任务假设你通过 SSH 登录并使用了命令行接口。 - 使用 TAB 键切换到 Customize 按钮,然后按 ENTER 键。Trusted Services 屏幕将会出现。
- 不要修改任何值,使用 TAB 键切换到 Forward 按钮,然后按 ENTER 键进入下一屏幕。Other Ports 屏幕将出现。
- 使用 TAB 键切换到 <Add> 按钮,然后按 ENTER 键。Port and Protocol 屏幕将会出现。
- 在 Port / Port Range 字段里输入
5445
,然后使用 TAB 键切换到 Protocol 字段,并输入tcp
。使用 TAB 键切换到 OK 按钮,然后按 ENTER 键。 - 使用 TAB 键切换到 Forward 按钮,直至你到达 Port Forwarding 屏幕。
- 使用 TAB 键切换到 <Add> 按钮,然后按 ENTER 键。
- 填写下列值以设立端口映射到 5445。
- 源接口:eth1
- 协议:tcp
- 端口 / 端口范围:5445
- 目的 IP 地址:10.1.1.2
- 端口 / 端口范围:5445
使用 TAB 键切换到 OK 按钮,然后按 ENTER。 - 使用 TAB 键切换到 Close 按钮,然后按 ENTER。
- 使用 TAB 键切换到 OK 按钮,然后按 ENTER。要应用这些改动,阅读警告提示并点击 Yes。
在你的 JBoss EAP 6 主机上配置防火墙。
一些机构选择在 JBoss EAP 6 服务器上配置防火墙,并关闭非操作必需的端口。请参考 第 9.4 节 “JBoss EAP 6 使用的网络端口” 并确定要打开的端口,然后关闭其他端口。红帽企业版 6 的默认配置关闭所有的端口,除了 22(用于 SSH)和 5353(用于多点传送 DNS)。当你在配置端口的时候,请确保你可以从物理上访问服务器,这样就不会不经意地将自己关在外面。
配置了防火墙,它会按照你在防火墙配置里指定的将通讯转发到内部的 JBoss EAP 6 服务器。如果你选择在服务器上启用防火墙,除了需要运行应用程序的端口,所有的端口将被关闭。
9.4. JBoss EAP 6 使用的网络端口
- 你的服务器组是否使用了默认的套接字绑定组,或者自定义的套接字绑定组。
- 单独部署的要求。
注意
默认的套接字绑定组
full-ha-sockets
full-sockets
ha-sockets
standard-sockets
表 9.1. 默认的套接字绑定组的引用
名称 | 端口 | 多点传送端口 | 描述 | 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 6 和 HTTP 加载平衡器之间通讯的多点传送端口。 | 是 | 否 | 是 | 否 | |
osgi-http | 8090 | 由使用 OSGi 子系统的内部组件使用。不能通过管理界面进行配置。 | 是 | 是 | 是 | 是 | |
remoting | 4447 | 用于远程 EJB 调用。 | 是 | 是 | 是 | 是 | |
txn-recovery-environment | 4712 | JTA 事务恢复管理者。 | 是 | 是 | 是 | 是 | |
txn-status-manager | 4713 | JTA / JTS 事务管理者。 | 是 | 是 | 是 | 是 |
除了套接字绑定组,每个主机控制台都打开另外两个端口用于管理:
- 9990 - Web 管理控制台的端口
- 9999 - 管理控制台和 API 使用的端口
第 10 章 管理接口的安全性
10.1. 保护管理接口
在测试环境里,我们通常在由管理控制台、管理 CLI 和其他 API 实现组成的管理接口上不设置安全层来运行 JBoss EAP 6 。这可以允许快速的开发和配置修改。
10.2. 默认的用户安全性配置
在 EAP 6 里,所有的管理接口都默认是有设置安全性的。这个安全性采取两种形式:
- 本地接口通过本地客户和服务器间的 SASL 合约设置安全性。这个安全机制基于客户访问本地文件系统的能力。这是因为访问本地文件系统会允许客户添加用户或修改配置以阻挠其他安全机制。如果对文件系统的物理访问可以实现,那么其他安全机制就是多余的。这个机制以四个步骤实现:
注意
即使你通过 HTTP 连接本地主机,HTTP 访问仍会视作远程的。- 客户发送一条消息给服务器,它包含一个用本地 SASL 机制验证的请求。
- 服务器生成一个一次性的令牌,将其写入到唯一的文件里,然后发送具有完整文件路径的消息给客户。
- 客户从文件里读取令牌并发送给服务器,检验它是否具有对文件系统的本地访问权限。
- 服务器验证令牌并删除这个文件。
- 远程客户,包括本地 HTTP 客户,使用基于区的安全性。带有使用管理接口远程配置 JBoss EAP 6 权限的默认区是
ManagementRealm
。我们提供了一个脚本,允许你添加用户到这个区(或者你创建的区)。请参考《JBoss EAP 6 安装指南》的 Getting Started 章节。对于每个用户,用户名,hased 密码,以及区都存储在文件里。- 受管域
EAP_HOME/domain/configuration/mgmt-users.properties
- 独立服务器
EAP_HOME/standalone/configuration/mgmt-users.properties
即使mgmt-users.properties
的内容都是以掩码显示的,这个文件仍必须作为敏感文件对待。我们推荐将其文件权限设置为600
,这样除了文件所有者,其他人都没有读或写的权限。
10.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 6 的用户的验证和授权。
ManagementRealm
和 ApplicationRealm
。每个安全区都使用一个 -users.properties
文件来存储用户和哈希密码,以及一个 -roles.properties
来存储用户和角色间的映射。相同也包含了对启用了 LDAP 的安全区的支持。
注意
一些安全区连接至外部接口,如 LDAP 服务器。转出连接(Outbound connection)定义了如何创建这种连接。预定义的连接类型,ldap-connection
,设置了连接 LDAP 服务器并验证凭证的所有必需和可选的属性。
管理接口包含如何连接和配置 JBoss EAP 的属性。这样的信息包括命名网络接口、端口、安全区和其他关于接口的可配置信息。默认安装里包含了两个接口:
http-interface
是基于 web 的管理控制台的配置。native-interface
是命令行管理 CLI 和类 REST 管理 API 的配置。
10.4. 禁用 HTTP 管理接口
注意
console-enabled
属性为 false
,而无需完全禁用这个接口。
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=console-enabled,value=false)
例 10.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"
}
}
例 10.2. 删除 HTTP 接口
/host=master/core-service=management/management-interface=http-interface/:remove
例 10.3. 重新创建 HTTP 接口
/host=master/core-service=management/management-interface=http-interface:add(console-enabled=true,interface=management,port="${jboss.management.http.port:9990}",security-realm=ManagementRealm)
10.5. 从默认的安全区删除无提示验证
JBoss EAP 6 的默认安装包含一个用于本地管理 CLI 用户的无提示验证(Silent Authentication)方法。这允许本地用户无需用户名或密码验证就可以访问管理 CLI。启用这个功能是为了方便,并协助本地用户无需验证就可以运行管理 CLI 脚本。它是一个非常有用的功能,特别是对本地配置的访问通常也会让用户可以添加自己的细节或禁用安全检查。
security-realm
部分里的 local
来实现。这适用于独立服务器的 standalone.xml
或受管域的 host.xml
。你应该只在理解了对特定服务器配置的影响后才考虑删除 local
元素。
local
元素。
例 10.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>
前提条件
- 启动 JBoss EAP 6 实例。
- 启动管理 CLI。
过程 10.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
里删除了。
10.6. 禁用对 JMX 子系统的远程访问
/profile=default
部分。对于独立服务器,请完全删除命令的这个部分。
注意
例 10.5. 从 JMX 子系统删除远程连接器。
/profile=default/subsystem=jmx/remoting-connector=jmx/:remove
例 10.6. 删除 JMX 子系统
/profile=default/subsystem=jmx/:remove
10.7. 为管理接口配置安全区
这个例子展示了 ManagementRealm
安全区的默认配置。它使用了一个名为 mgmt-users.properties
的文件来保存其配置信息。
例 10.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
的安全区并为相关的配置文件设置了目录。
例 10.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)
添加了安全区后,将其名称作为引用提供给管理接口。
例 10.9. 在管理接口里添加一个安全区
/host=master/core-service=management/management-interface=http-interface/:write-attribute(security-realm=TestRealm)
10.8. 为独立模式下的管理控制台配置 HTTPS
过程 10.2.
- 通过添加
management-https
配置并删除management-http
配置,确保管理控制台捆绑了HTTPS
。这可以通过编辑standalone.xml
文件(我们不推荐这么做)或者使用下列 CLI 接口命令来完成:/core-service=management/management-interface=http-interface:write-attribute(name=secure-socket-binding, value=management-https)
/core-service=management/management-interface=http-interface:undefine-attribute(name=socket-binding)
可选的:
如果你使用了自定义的socket-binding
组,请确保已定义了management-https
(这是默认选项,绑定了端口9443
)。<socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}"> <socket-binding name="management-native" interface="management" port="${jboss.management.native.port:9999}"/> <socket-binding name="management-http" interface="management" port="${jboss.management.http.port:9990}"/> <socket-binding name="management-https" interface="management" port="${jboss.management.https.port:9443}"/>
- 按照 第 8.4 节 “生成 SSL 密钥和证书” 里讨论的步骤生成密钥对。
- 在
standalone.xml
配置文件的security-realm
部分添加一个server-identities
元素。在这个元素里,你要定义用于密钥对的密钥库的路径、密钥库的密码和别名。执行下列 CLI 命令,请用自己的值来替换例子里的值。这个例子假设密钥库被复制到服务器的配置目录,对于独立服务器来说,也就是EAP_HOME/standalone/configuration/
。/core-service=management/security-realm=ManagementRealm/server-identity=ssl:add(keystore-path=server.keystore,keystore-relative-to=jboss.server.config.dir, keystore-password=SECRET, alias=KEY_ALIAS)
- 重启你的独立服务器。
10.9. 为域模式下的管理控制台配置 HTTPS
过程 10.3.
- 按照 第 8.4 节 “生成 SSL 密钥和证书” 里讨论的步骤生成密钥对。
- 在
host.xml.
配置文件的security-realm
部分添加一个server-identities
元素。在这个元素里,你要定义用于密钥对的密钥库的路径、密钥库的密码和别名。执行下列 CLI 命令,请用自己的值来替换例子里的值。这个例子假设密钥库被复制到服务器的配置目录,对于受管域来说,也就是 EAP_HOME/domain/configuration/ 。/host=master/core-service=management/security-realm=ManagementRealm/server-identity=ssl:add(protocol=TLSv1, keystore-path=server.keystore,keystore-relative-to=jboss.domain.config.dir, keystore-password=SECRET, alias=KEY_ALIAS)
- 通过添加
secure-port
配置并删除端口配置,修改management-interface
部分里 socket 元素。请使用下列名:/host=master/core-service=management/management-interface=http-interface:write-attribute(name=secure-port,value=9443)
/host=master/core-service=management/management-interface=http-interface:undefine-attribute(name=port)
- 重启你的域。
10.10. 对管理接口和 CLI 使用双向 SSL
- HOST1
- JBoss 服务器的主机名。例如,
jboss.redhat.com
。 - HOST2
- 客户的名称。例如
myclient
。请注意,这并不需要实际的主机名。 - CA_HOST1
- 用于 HOST1 证书的标识名(DN)。例如
cn=jboss,dc=redhat,dc=com
。 - CA_HOST2
- 用于 HOST2 证书的标识名(DN)。例如
cn=myclient,dc=redhat,dc=com
。
过程 10.4.
- 生成库:
keytool -genkeypair -alias HOST1_alias -keyalg RSA -keysize 1024 -validity 365 -keystore host1.keystore.jks -dname "CA_HOST1" -keypass secret -storepass secret
keytool -genkeypair -alias HOST2_alias -keyalg RSA -keysize 1024 -validity 365 -keystore host2.keystore.jks -dname "CA_HOST2" -keypass secret -storepass secret
- 导出证书:
keytool -exportcert -keystore HOST1.keystore.jks -alias HOST1_alias -keypass secret -storepass secret -file HOST1.cer
keytool -exportcert -keystore HOST2.keystore.jks -alias HOST2_alias -keypass secret -storepass secret -file HOST2.cer
- 将证书导入到对应的信任库:
keytool -importcert -keystore HOST1.truststore.jks -storepass secret -alias HOST2_alias -trustcacerts -file HOST2.cer
keytool -importcert -keystore HOST2.truststore.jks -storepass secret -alias HOST1_alias -trustcacerts -file HOST1.cer
- 在配置文件(
host.xml
或standalone.xml
)里定义一个 CertificateRealm 并让接口指向它:这可以通过编辑配置文件文件(我们不推荐这么做)或者使用下列命令来完成:/core-service=management/security-realm=CertificateRealm:add()
/core-service=management/security-realm=CertificateRealm:add/server-identity=ssl:add(keystore-path=/path/to/HOST1.keystore.jks,keystore-password=secret, alias=HOST1_alias)
/core-service=management/security-realm=CertificateRealm/authentication=truststore:add(keystore-path=/path/to/HOST1.truststore.jks,keystore-password=secret)
- 编辑
JBOSS_HOME/bin/jboss-cli.xml
并添加 SSL 配置(使用合适的值):<ssl> <alias>$HOST2alias</alias> <key-store>/path/to/HOST2.keystore.jks</key-store> <key-store-password>secret</key-store-password> <trust-store>/path/to/HOST2.truststore.jks</trust-store> <trust-store-password>secret</trust-store-password> <modify-trust-store>true</modify-trust-store> </ssl>
10.11. 用于敏感字符串的密码库
10.11.1. 关于保护明码文件里的敏感字符
警告
java.io.IOException: com.sun.crypto.provider.SealedObjectForKeyProtector
10.11.2. 创建一个 Java 密钥库来存储敏感信息
前提条件
keytool
命令必须可用。它时 JRE 提供的命令。请找到这个文件所在的位置,在红帽企业版 Linux 里,它是/usr/bin/keytool
。
过程 10.5. 设置 Java 密钥库
创建一个目录来存储你的密钥库和其他加密的信息。
创建一个目录来存储你的密钥库和其他加密的信息。这个过程的剩余部分将假设这个目录是/home/USER/vault/
。确定
keytool
要使用的参数。确定下列参数:- alias
- 别名是 vault 或其他存储在密钥库里的数据的唯一标识符。这个过程结尾的命令示例里的别名是
vault
。别名是区分大小写的。 - keyalg
- 用于加密的算法。这个过程里的例子使用了
RSA
。请查看你的 JRE 和操纵系统的文档,看那种选择是可用的。 - keysize
- 加密密钥的大小影响了通过 brute force 解密的难度。这个过程里的例子使用了
2048
。关于合适的值的信息,请参考keytool
所附带的文档。 - keystore
- 密钥库是一个保存加密信息以及如何解密的信息的数据库。如果你没有指定密钥库,默认的密钥库是你的主目录下的
.keystore
。当第一次添加数据到密钥库时,它会被创建。这个过程里的例子使用了vault.keystore
密钥库。
keytool
命令有很多其他选项。更多的细节,请参考你的 JRE 或操纵系统的文档。确定
keystore
命令会询问的问题的答案。keystore
需要下列信息来填充密钥库条目:- 密钥库密码
- 当你创建一个密钥库时,你必须设置密码。为了和将来的密钥库一起使用,你需要提供密码。请选择一个你可以记住的强密码。密钥库的安全性取决于密码以及它所在的文件系统和操纵系统的安全性。
- 密钥密码(可选)
- 除了密钥库密码,你可以为每个保存的密钥指定一个密码。每次使用这个密钥时都需要输入密码。通常这个功能不会被使用。
- 名和姓
- 这和列表里余下的信息可以有助于唯一标识密钥并将其放入一个其他密钥的层次结构里。它完全可以不是一个名字,但应该是两个单词,而且是唯一的。这个过程里的例子使用了
Accounting Administrator
。按照目录的术语,它成为了证书的通用名称(common name)。 - 机构内部门(Organizational unit)
- 这是一个标识谁在使用证书的单词。它可以是应用程序或商业单元。这个过程里的例子使用了
AccountingServices
。通常,组或应用程序使用的所有密钥库都使用相同的机构内部门。 - 机构
- 这通常是一个代表你的机构名称的单词。它通常在机构使用的所有证书里都保持相同。这个例子使用了
MyOrganization
。 - 城市或自治区
- 你的城市
- 州或省
- 你的州或省,或者相等的地区
- 国家
- 两个字母的国家代码
所有这些信息将创建一个密钥库和证书的层次结构,确保它们使用一致而唯一的命名结构。运行
keytool
命令,提供你收集的信息。例 10.10.
keystore
命令的输入和输出的例子。$ keytool -genseckey -alias vault -storetype jceks -keyalg AES -keysize 128 -storepass vault22 -keypass vault22 -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 6 保存加密字符串,如密码。
10.11.3. 设置密钥库密码的掩码并初始化密码库
前提条件
EAP_HOME/bin/vault.sh
应用程序需要可以通过命令行界面来访问。
运行
vault.sh
命令。运行EAP_HOME/bin/vault.sh
。输入0
启动新的交互式会话。输入保存加密文件的目录。
这个目录应该比较安全,但 JBoss EAP 6 需要能够访问它。如果你按照 第 10.11.2 节 “创建一个 Java 密钥库来存储敏感信息” 进行,你的密钥库应该位于主目录的vault/
里。这个例子使用了目录/home/USER/vault/
。注意
不要忘记目录名后面的斜杠。根据操作系统来使用/
或\
。输入密钥库的路径。
输入密钥库文件的完整路径。这个例子使用了/home/USER/vault/vault.keystore
。加密密钥库的密码。
下面的步骤加密了密钥库的密码,所以你可以在配置文件和应用程序里安全地使用它了。输入密钥库的密码。
遇到提示时,输入密钥库的密码。输入一个 salt 值。
输入 8 个字符的 salt 值。这个 salt 值和下面的迭代计数用于创建哈希值。输入迭代计数。
输入迭代计数的值。记录密码掩码信息。
密码掩码、salt 和迭代计数都输出在标准输出里。将其记录在一个安全的位置。攻击者可能用它们来破解密码。输入 vault 的别名。
遇到提示时,输入 vault 的别名。如果你按照 第 10.11.2 节 “创建一个 Java 密钥库来存储敏感信息” 来创建 vault,那么别名应该是vault
。
退出交互式控制台。
输入2
来退出交互式控制台。
你的密钥库密码已设置掩码,可用于配置文件和部署了。此外,你的 vault 已配置完全且可以使用了。
10.11.4. 配置 JBoss EAP 6 来使用密码库
在你可以在配置文件里为密码设置掩码和其他敏感属性之前,你需要让 JBoss EAP 6 知晓存储和破解密码的密码库。请按照下列步骤来启用这个功能。
过程 10.6. 设置密码库
确定这个命令的正确的值。
确定下列参数的值,这个命令将用它们来创建密钥库。关于创建密钥库的信息,请参考下列主题:第 10.11.2 节 “创建一个 Java 密钥库来存储敏感信息” 和 第 10.11.3 节 “设置密钥库密码的掩码并初始化密码库”。参数 描述 KEYSTORE_URL 密钥库文件的 URL 的文件系统路径,它通常类似于vault.keystore
。KEYSTORE_PASSWORD 用来访问密钥库的密码。这个值应该被标记。KEYSTORE_ALIAS 密钥库的名称。SALT 用来加密和解密密钥库值的 Salt。ITERATION_COUNT 运行加密算法的次数。ENC_FILE_DIR 密钥库命令运行的目录路径。通常是包含密码库的目录。host (managed domain only) 你在配置的主机的名称使用管理 CLI 来启用密码库。
根据使用的是受管域还是独立服务器配置,分别运行下列命令。用这个步骤里第一步里的值替换命令里的值。注意
如果你使用的是 Microsoft Windows 服务器,请用 4 个\
字符替换文件或目录里的每个/
字符。这是因为它需要两个\
来作为脱字符。对于其他/
字符则不需要这么做。受管域
/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 6 已配置好通过密码库来破解掩码字符串。要添加字符串到库里并在配置里使用它们,请参考下列主题:第 10.11.5 节 “在 Java 密钥库里保存和获取加密的敏感字符串”。
10.11.5. 在 Java 密钥库里保存和获取加密的敏感字符串
在普通文本配置文件里包含密码和其他敏感字符串是不安全的。JBoss EAP 6 包括了在加密的密钥库里存储并为这些敏感字符串设置掩码,以及在配置文件里使用掩码值。
前提条件
EAP_HOME/bin/vault.sh
应用程序需要可以通过命令行界面来访问。
过程 10.7. 设置 Java 密钥库
运行
vault.sh
命令。运行EAP_HOME/bin/vault.sh
。输入0
启动新的交互式会话。输入保存加密文件的目录。
如果你遵循 第 10.11.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 Configuration should be done as follows: VAULT::ds_ExampleDS::password::1 ********************************************
在你的配置里使用加密的字符串。
在你的配置里使用前面步骤里的字符串来替代普通文本字符串。下面是使用加密密码的数据源。... <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::1}</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::1}</password>
10.11.6. 存储和解析应用程序里的敏感字符串
JBoss EAP 6 的 Configuration 元素支持使用安全库(Security Vault)机制根据 Java 密钥库里保存的值来解析加密的字符串。你可以在自己的应用程序里添加对这个功能的支持。
在执行这个过程之前,请确保保存库文件的目录是存在的。将其保存在什么位置是无所谓的,只要执行 JBoss EAP 6 的用户有读写这些文件的权限。这个例子将 vault/
目录放到 /home/USER/vault/
目录里。这个库本身也是 vault/
里一个名为 vault.keystore
的文件。
例 10.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 Configuration should be done as follows: VAULT::DS::thePass::1 ******************************************** Please enter a Digit:: 0: Store a password 1: Check whether password exists 2: Exit2
VAULT
开始的行。
例 10.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::1", 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) + ""); } }
10.12. LDAP
10.12.1. 关于 LDAP
10.12.2. 在管理接口里使用 LDAP 进行验证
- 创建一个到 LDAP 服务器的转出连接。
- 创建一个启用 LDAP 的安全区。
- 在管理接口里引用新的安全区。
LDAP 转出连接允许下列属性:
表 10.1. LDAP 转出连接的属性
属性 | 要求的 | 描述 |
---|---|---|
url | 是 |
目录服务器的 URL 地址。
|
search-dn | 是 |
授权执行搜索的用户的全限定可区分名称(Distinguished Name,DN)。
|
search-credentials | 是 |
用户授权执行搜索的密码。
|
initial-context-factory | 否 |
当建立连接时使用的初始上下文。默认为
com.sun.jndi.ldap.LdapCtxFactory 。
|
security-realm | 否 |
为了获得建立连接时所需的已配置的
SSLContext 而引用的安全区。
|
例 10.13. 添加 LDAP 转出连接
- 搜索 DN:
cn=search,dc=acme,dc=com
- 搜索凭证:
myPass
- URL:
ldap://127.0.0.1:389
/host=master/core-service=management/security-realm=ldap_security_realm:add
/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")
管理接口可以针对 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))
例 10.14. 代表启用了 LDAP 的安全区的 XML 片段
- connection -
ldap_connection
- base-dn -
cn=users,dc=acme,dc=com
. - username-filter -
attribute="sambaAccountName"
<security-realm name="ldap_security_realm"> <authentication> <ldap connection="ldap_connection" base-dn="cn=users,dc=acme,dc=com"> <username-filter attribute="sambaAccountName" /> </ldap> </authentication> </security-realm>
警告
例 10.15. 添加 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 验证。
例 10.16. 应用安全区到 HTTP 接口里
/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=ldap-security-realm)
要配置受管域里的主机根据 Microsoft Active Directory 来验证,请按照这个过程来进行,它创建了一个安全域并使用 JAAS 验证映射角色到活动目录组。这个过程是必需的,因为 Microsoft Active Directory 允许用空的密码进行绑定。这个过程防止了在应用程序平台里使用空的密码。
master
。
添加一个名为
ldap_security_realm
的新的<security-realm>
,并配置它使用 JAAS。下列管理 CLI 命令添加了新的安全区并设置了它的验证机制。请按需要修改主机的名称。/host=master/core-service=management/security-realm=ldap_security_realm/:add
/host=master/core-service=management/security-realm=ldap_security_realm/authentication=jaas/:add(name=managementLDAPDomain)
配置
<http-interface>
以使用这个新的安全区。下列管理 CLI 命令配置了 HTTP 接口。/host=master/core-service=management/management-interface=http-interface/:write-attribute(name=security-realm,value=ldap_security_realm)
配置 JBoss EAP,在其启动参数里添加自定义的 JAAS 配置。
编辑EAP_HOME/bin/domain.conf
文件。搜索HOST_CONTROLLER_JAVA_OPTS
变量。这是你添加 JBoss EAP 启动前所需的 JVM 指令的地方。下面是这个参数的默认内容的示例:HOST_CONTROLLER_JAVA_OPTS="$JAVA_OPTS"
添加下列指令:-Djava.security.auth.login.config=/opt/jboss-eap-6.0/domain/configuration/jaas.conf"
被编辑的行类似于:-Djava.security.auth.login.config=/opt/jboss-eap-6.0/domain/configuration/jaas.conf"
在模块选项里添加登陆模块。
在相同的文件里,找到包含下列内容的行:JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman"
修改它为下面的样子请确保不要插入任何多余的空格。JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman,com.sun.security.auth.login"
保存并关闭domain.conf
文件。创建将添加至 classpath 的 JAAS 配置。
在下列位置创建一个新的文件:EAP_HOME/domain/configuration/jaas.conf
这个文件应该包含下列内容。请按照自己的环境编辑相关的参数。managementLDAPDomain { org.jboss.security.auth.spi.LdapExtLoginModule required java.naming.factory.initial="com.sun.jndi.ldap.LdapCtxFactory" java.naming.provider.url="ldap://your_active_directory_host:389" java.naming.security.authentication="simple" bindDN="cn=Administrator,cn=users,dc=domain,dc=your_company,dc=com" bindCredential="password" baseCtxDN="cn=users,dc=domain,dc=redhat,dc=com" baseFilter="(&(sAMAccountName={0})(|(memberOf=cn=Domain Guests,cn=Users,dc=domain,dc=acme,dc=com)(memberOf=cn=Domain Admins,cn=Users,dc=domain,dc=acme,dc=com)))" allowEmptyPasswords="false" rolesCtxDN="cn=users,dc=domain,dc=acme,dc=com" roleFilter="(cn=no such group)" searchScope="SUBTREE_SCOPE"; };
- 重启 JBoss EAP,你的 HTTP 接口应该使用 LDAP 服务器来验证了。
第 11 章 用基于角色的访问控制来保护管理接口
11.1. 关于基于角色的访问控制(Role-Based Access Control,RBAC)
11.2. GUI 和 CLI 的基于角色的访问控制
- 管理控制台
- 在管理控制台里,根据你分配的角色的权限,有些控件和视图是禁用的(灰色)或不可见的。如果你没有对某个资源属性的读权限,该权限将在控制台里显示为空白。例如,多数角色无法读取数据源的用户名和密码字段。如果你没有对某个资源属性的写权限,该权限将在资源编辑表单里显示为禁用(灰色)。如果你根本没有对这个资源的写权限,那么整个编辑表单都不会出现。如果你没有对某个资源或属性的访问权限(就是对于你的角色来说是“不可寻址的”),那它们根本不会出现在在控制台里。其中一个例子是,访问控制系统自身在默认情况下只对一些角色可见。
- 管理 API
- 启用了 RBAC 后,使用
jboss-cli.sh
工具或直接使用 API 的用户在 API 里会遇到稍许不同的行为。无法读取的资源和属性将从结果里过滤。如果被过滤的内容是角色可以寻址的,那么它们的名称将列为结果里response-headers
部分的filtered-attributes
。如果它们是无法被寻址的,那根本不会被列出。试图访问不能寻址的资源将导致 "resource not found" 错误。如果用户试图写入或读取他们可以寻址的资源但缺乏对应的读写权限,就会返回 "Permission Denied" 。
11.3. 支持的验证模式
username/password
、client certificate
和 local user
。
- Username/Password
- 用户通过用户名和密码组合根据
mgmt-users.properties
文件或 LDAP 服务器来进行检验。 - Client Certificate
- 使用信任库。
- Local User
- 如果服务器运行在相同的服务器上,
jboss-cli.sh
将自动验证为本地用户。在默认情况下,本地用户是SuperUser
组的成员。
mgmt-users.properties
文件或 LDAP 服务器来验证时,这些系统可以提供用户组信息。JBoss EAP 也可以使用这些信息来为用户分配角色。
11.4. 标准角色
- Monitor
- 充当 Monitor 角色的用户具有最小的权限且只能读取服务器的当前配置和状态。这个角色是为了那些需要跟踪和报告服务器性能的用户而设计的。Monitor 角色既不能修改服务器配置也不能访问敏感数据或操作。
- Operator
- Operator 角色扩展了 Monitor 角色,它添加了修改服务器的运行时状态的能力。这表示 Operator 可以重载并关闭服务器,也可以暂停和恢复 JMS 目的地。Operator 角色对于负责应用服务器的物理或虚拟主机的用户是很理想的,他们可以确保有需要时关闭和重启服务器。Operator 角色既不能修改服务器配置也不能访问敏感数据或操作。
- Maintainer
- Maintainer 角色可以查看和修改运行时状态以及除了敏感数据和操作之外的所有配置。Maintainer 角色是普通用途的角色,它不能访问敏感数据和操作。Maintainer 角色赋予用户几乎完整的管理服务器的权限,但不能访问密码和其他敏感信息。Maintainer 角色不能访问敏感数据或操作。
- Administrator
- Administrator 角色具有对服务器上除了审计日志系统以外的所有资源和操作的无限制的访问权限。 Administrator 是唯一(除了 SuperUser)可以访问敏感数据和操作的角色。这个角色也可以配置访问控制系统。只有处理敏感数据或配置用户和角色时才要求 Administrator 角色。
- SuperUser
- SuperUser 角色没有任何限制,它可以访问任何服务器的资源和操作,包括审计日志系统。这个角色等同于以前的 JBoss EAP 6 版本(6.0 和 6.1)里的管理员用户。如果禁用了 RBAC,所有的管理用户都会拥有和 SuperUser 角色相同的权限。
- Deployer
- Deployer 角色具有和 Monitor 相同的角色,但它可以修改部署的配置和状态以及其他启用为应用程序资源的资源类型。
- Auditor
- Auditor 角色具有 Monitor 角色的所有权限,它也可以查看(但不能修改)敏感数据,且具有对审计日志系统的完全权限。Auditor 是除了 SuperUser 之外唯一能够访问审计日志系统的角色。Auditor 角色不能修改敏感数据或资源。它只有读的权限。
11.5. 关于角色权限
表 11.1. 角色权限矩阵
Monitor
|
Operator
|
Maintainer
|
Deployer
|
Auditor
|
Administrator
|
SuperUser
| |
读取配置和状态
|
X
|
X
|
X
|
X
|
X
|
X
|
X
|
读取敏感数据 [2]
|
X
|
X
|
X
| ||||
修改敏感数据 [2]
|
X
|
X
| |||||
读/修改审计日志
|
X
|
X
| |||||
修改运行时状态
|
X
|
X
|
X[1]
|
X
|
X
| ||
修改持久性配置
|
X
|
X[1]
|
X
|
X
| |||
读/修改访问控制
|
X
|
X
|
11.6. 关于约束
- 应用程序约束
- 应用程序约束定义了可以被具有部署角色的用户访问的资源和属性集合。在默认情况下,唯一被启用的应用程序约束是 core,它包含部署、部署重叠。应用程序约束也包含在 datasources、logging、mail、messaging、naming、resource-adapters 和 security 里(默认不会启用)。这些约束允许 Deployer 用户不仅可以部署应用程序,还可以配置和维护应用程序要求的资源。应用程序约束的配置位于管理 API 里的
/core-service=management/access=authorization/constraint=application-classification
。 - 敏感性约束
- 敏感性约束定义了被认为是 “敏感的”的资源的集合。敏感的资源通常是某种机密的内容,如密码,或者对服务器的操作有着重大影响的东西,如网络、JVM 配置或系统属性。访问控制系统本身也被视作敏感的资源。唯一对敏感资源具有写权限的角色是 Administrator 和 SuperUser。Auditor 角色只能读取敏感资源。其他角色都没有访问权限。应用程序约束的配置位于管理 API 里的
/core-service=management/access=authorization/constraint=sensitivity-classification
。 - 库表达式约束
- 库表达式(Vault Expression)约束定义了读/写库表达式是否被视作敏感操作。在默认情况下,这两者都是敏感操作。库表达式约束的配置位于管理 API 的
/core-service=management/access=authorization/constraint=vault-expression
。
11.7. 关于 JMX 和基于角色的访问控制
- JBoss EAP 6 的 Management API 开放为 JMX Management Bean。这些 Management Bean 被称为 "core mbeans",对它们的访问和过滤同底层的 Management API 是一模一样的。
- JMX 子系统的写权限被配置为“敏感的”。这表示只有 Administrator 和 SuperUser 角色可以修改这个子系统。而 Auditor 角色可以读取子系统的配置。
- 在默认情况下,部署的应用程序和服务(non-core mbeans)注册的 Management Bean 可以被管理用户访问,但只有 Maintainer、Operator、Administrator、SuperUser 角色可以写入它。
11.8. 配置基于角色的访问控制
11.8.1. RBAC 配置任务概述
- 查看和配置用户分配(或排斥)了哪些角色
- 查看和配置组分配(或排斥)了哪些角色
- 查看每个角色的组和用户成员资格。
- 配置每个角色默认成员资格。
- 常见具有作用域的角色
- 启用和禁用 RBAC
- 修改权限组合策略
- 配置应用程序资源和资源敏感性约束
11.8.2. 启用基于角色的访问控制
simple
修改为 rbac
就可以启用它。你可以用 jboss-cli.sh
工具来完成,或者当服务器下线时编辑服务器配置 XML 文件。如果在运行的服务器上禁用或启用 RBAC,在生效前必须重载服务器配置。
jboss-cli.sh
运行在和服务器相同的主机上,它是以 SuperUser 角色运行的。
过程 11.1. 启用 RBAC
- 要用
jboss-cli.sh
启用 RBAC,请使用访问授权资源的write-attribute
操作来设置提供者的属性为rbac
。/core-service=management/access=authorization:write-attribute(name=provider, value=rbac)
[standalone@localhost:9999 /] /core-service=management/access=authorization:write-attribute(name=provider, value=rbac) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } } [standalone@localhost:9999 /] /:reload { "outcome" => "success", "result" => undefined } [standalone@localhost:9999 /]
过程 11.2. 禁用 RBAC
- 要用
jboss-cli.sh
禁用 RBAC,请使用访问授权资源的write-attribute
操作来设置提供者的属性为simple
。/core-service=management/access=authorization:write-attribute(name=provider, value=simple)
[standalone@localhost:9999 /] /core-service=management/access=authorization:write-attribute(name=provider, value=simple) { "outcome" => "success", "response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } } [standalone@localhost:9999 /] /:reload { "outcome" => "success", "result" => undefined } [standalone@localhost:9999 /]
provider
属性,设置为 rbac
则启用, simple
则禁用 RBAC。
<management> <access-control provider="rbac"> <role-mapping> <role name="SuperUser"> <include> <user name="$local"/> </include> </role> </role-mapping> </access-control> </management>
11.8.3. 修改权限组合策略
permissive
或 rejecting
。默认选项是 permissive
。
permissive
时,如果任何角色被分配给用户,那这个角色许可的动作将会被允许执行。
rejecting
时,如果许可某个动作的多个角色被分配给用户,那这个动作将不会被允许执行。
rejecting
时,具有多个角色的用户将不能使用管理控制台或 jboss-cli.sh
。
permission-combination-policy
属性为 permissive
或 rejecting
来配置的。这可以用 jboss-cli.sh
工具或编辑服务器配置 XML 文件(如果服务器已下线)来完成。
过程 11.3. 设置权限组合策略
- 使用访问授权资源的
write-attribute
操作来设置permission-combination-policy
为所需的策略名称。/core-service=management/access=authorization:write-attribute(name=permission-combination-policy, value=POLICYNAME)
有效的策略名称是 rejecting 和 permissive。[standalone@localhost:9999 /] /core-service=management/access=authorization:write-attribute(name=permission-combination-policy, value=rejecting) {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
permission-combination-policy
属性。
<access-control provider="rbac" permission-combination-policy="rejecting"> <role-mapping> <role name="SuperUser"> <include> <user name="$local"/> </include> </role> </role-mapping> </access-control>
11.9. 管理角色
11.9.1. 关于角色成员资格
- 用户被:
- 列在角色包含列表里,或者
- 是列在角色包含列表里的组的成员。
- 用户没有被:
- 列在角色排除列表里,或者
- 是列在角色排除列表里的组的成员。
jboss-cli.sh
工具来完成。
11.9.2. 配置用户和角色的分配
jboss-cli.sh
进行配置。本节只展示如何使用管理控制台来完成。
- 登陆到管理控制台。
- 点击『Administration』标签页。
- 展开左侧的『Access Control』并选择『Role Assignment』。
- 选择『USERS』标签页。
图 11.1. 管理控制台里的用户角色管理
过程 11.4. 为用户创建新的角色分配
- 登陆到管理控制台。
- 进入『Role Assignment』的『Users』标签页。
- 点击用户列表右上角的『Add』按钮。『Add User』对话框会出现。
图 11.2. 『Add User』对话框
- 指定用户名,可选择输入区名。
- 选择是包含(include)还是排除(exclude)。
- 点击角色旁的复选框。你可以使用 Ctl 键(OSX 上的 Command 键)来选择多个选项。
- 点击『Save』按钮。保存成功后,『Add User』对话框将会关闭,用户列表将会更新以反映所作的修改。如果不成功则会显示 "Failed to save role assignment" 消息。
过程 11.5. 更新用户的角色分配
- 登陆到管理控制台。
- 进入『Role Assignment』的『Users』标签页。
- 从列表里选择用户。
- 点击『Edit』。『Selection』面板将进入编辑模式。
图 11.3. 『Selection』面板的编辑视图
在这里你可以添加和删除所分配或排除的角色。- 要添加被分配的角色,从左侧的『Available roles』列表里进行选择并点击『Assigned roles』列表旁的右箭头。角色将从可用列表移至『Assigned roles』列表。
- 要删除被分配的角色,从右侧的『Assigned roles』列表里选择要删除的角色,并点击旁边的左箭头。角色将从『Assigned roles』列表移至『Available roles』列表。
- 要添加被排除的角色,从左侧的『Available roles』列表里进行选择并点击『Excluded roles』列表旁的右箭头。角色将从可用列表移至『Excluded roles』列表。
- 要删除被排除的角色,从右侧的『Excluded roles』列表里选择要删除的角色,并点击旁边的左箭头。角色将从『Excluded roles』列表移至『Available roles』列表。
- 点击『Save』按钮。成功后,编辑视图将会关闭,用户列表将会更新以反映所作的修改。如果不成功则会显示 "Failed to save role assignment" 消息。
过程 11.6. 删除用户的角色分配
- 登陆到管理控制台。
- 进入『Role Assignment』的『Users』标签页。
- 从列表里选择用户。
- 点『Remove』按钮。『Remove Role Assignment』确认框将出现。
- 点击『Confirm』按钮。成功后,用户将不会再出现在用户角色分配的列表里。
重要
11.9.3. 用 jboss-cli.sh 配置用户角色分配
jboss-cli.sh
进行配置。本节只展示如何使用 jboss-cli.sh
工具来完成。
/core-service=management/access=authorization
as role-mapping
元素。
过程 11.7. 查看角色分配配置
- 使用 :read-children-names 操作来获取配置角色的完整列表:
/core-service=management/access=authorization:read-children-names(child-type=role-mapping)
[standalone@localhost:9999 access=authorization] :read-children-names(child-type=role-mapping) { "outcome" => "success", "result" => [ "ADMINISTRATOR", "DEPLOYER", "MAINTAINER", "MONITOR", "OPERATOR", "SuperUser" ] }
- 使用指定 role-mapping 的
read-resource
操作来获取某个角色的完整细节:/core-service=management/access=authorization/role-mapping=ROLENAME:read-resource(recursive=true)
[standalone@localhost:9999 access=authorization] ./role-mapping=ADMINISTRATOR:read-resource(recursive=true) { "outcome" => "success", "result" => { "include-all" => false, "exclude" => undefined, "include" => { "user-theboss" => { "name" => "theboss", "realm" => undefined, "type" => "USER" }, "user-harold" => { "name" => "harold", "realm" => undefined, "type" => "USER" }, "group-SysOps" => { "name" => "SysOps", "realm" => undefined, "type" => "GROUP" } } } } [standalone@localhost:9999 access=authorization]
过程 11.8. 添加新的角色
- 使用
add
操作来添加新的角色配置。/core-service=management/access=authorization/role-mapping=ROLENAME:add
ROLENAME 是新映射使用的角色的名称。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR:add {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
过程 11.9. 添加包含在角色里的用户
- 请使用
add
操作来添加用户到角色的包含列表里。/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:add(name=USERNAME, type=USER)
ROLENAME 是被配置的角色的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如user-USERNAME
。USERNAME 是添加到包含列表里的用户的名称。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/include=user-max:add(name=max, type=USER) {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
过程 11.10. 添加角色所排除的用户
- 请使用
add
操作来添加用户到角色的排除列表里。/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:add(name=USERNAME, type=USER)
ROLENAME 是被配置的角色的名称。USERNAME 是添加到排除列表里的用户的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如user-USERNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/exclude=user-max:add(name=max, type=USER) {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
过程 11.11. 删除用户的角色包含配置
- 请使用
remove
操作来删除这个条目。/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:remove
ROLENAME 是被配置的角色的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如user-USERNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/include=user-max:remove {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
从包含列表里删除用户并不会从系统删除这个用户,也不能保证角色不会被分配给这个用户。这个角色仍可能根据组成员资格分配给它。
过程 11.12. 删除用户的角色排除配置
- 请使用
remove
操作来删除这个条目。/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:remove
ROLENAME 是被配置的角色的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如user-USERNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/exclude=user-max:remove {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
从排除列表里删除用户并不会从系统删除这个用户,也不能保证角色被分配给这个用户。这个角色仍可能根据组成员资格被排除。
11.9.4. 关于角色和用户组
mgmt-users.properties
文件或 LDAP 服务器验证的用户可以是用户组的成员。用户组是可以分配给一个或多个用户的任意标签。
mgmt-users.properties
文件时,组信息保存在 mgmt-groups.properties
文件里。当使用 LDAP 时,组信息保存在 LDAP 服务器里并由负责 LDAP 服务器的人员来维护。
11.9.5. 配置组角色的分配
jboss-cli.sh
进行配置。本节只展示如何使用管理控制台来完成。
- 登陆到管理控制台。
- 点击『Administration』标签页。
- 展开左侧的『Access Control』并选择『Role Assignment』。
- 选择『GROUPS』标签页。
图 11.4. 管理控制台里的组角色管理
过程 11.13. 为组创建新的角色分配
- 登陆到管理控制台
- 进入『Role Assignment』的『GROUPS』标签页。
- 点击用户列表右上角的『Add』按钮。『Add Group』对话框会出现。
图 11.5. 『Add Group』对话框
- 指定组名,可选择输入区名。
- 选择是包含(include)还是排除(exclude)。
- 点击角色旁的复选框。你可以使用 Ctl 键(OSX 上的 Command 键)来选择多个选项。
- 点击『Save』按钮。保存成功后,『Add Group』对话框将会关闭,组列表将会更新以反映所作的修改。如果不成功则会显示 "Failed to save role assignment" 消息。
过程 11.14. 更新组的角色分配
- 登陆到管理控制台。
- 进入『Role Assignment』的『GROUPS』标签页。
- 从列表里选择组。
- 点击『Edit』。『Selection』面板将进入编辑模式。
图 11.6. 『Selection』视图编辑模式
在这里你可以添加和删除组里分配或排除的角色:- 要添加被分配的角色,从左侧的『Available roles』列表里进行选择并点击『Assigned roles』列表旁的右箭头。角色将从可用列表移至『Assigned roles』列表。
- 要删除被分配的角色,从右侧的『Assigned roles』列表里选择要删除的角色,并点击旁边的左箭头。角色将从『Assigned roles』列表移至『Available roles』列表。
- 要添加被排除的角色,从左侧的『Available roles』列表里进行选择并点击『Excluded roles』列表旁的右箭头。角色将从可用列表移至『Excluded roles』列表。
- 要删除被排除的角色,从右侧的『Excluded roles』列表里选择要删除的角色,并点击旁边的左箭头。角色将从『Excluded roles』列表移至『Available roles』列表。
- 点击『Save』按钮。成功后,编辑视图将会关闭,组列表将会更新以反映所作的修改。如果不成功则会显示 "Failed to save role assignment" 消息。
过程 11.15. 删除组的角色分配
- 登陆到管理控制台。
- 进入『Role Assignment』的『GROUPS』标签页。
- 从列表里选择组。
- 点『Remove』按钮。『Remove Role Assignment』确认框将出现。
- 点击『Confirm』按钮。成功后,组将不会再出现在用户角色分配的列表里。从角色分配列表里删除组并不会从系统删除这个用户组,也不能保证没有角色被分配给这个组。每个组成员仍可能被直接分配角色。
11.9.6. 用 jboss-cli.sh 配置组角色
jboss-cli.sh
进行配置。本节只展示如何使用 jboss-cli.sh
工具来完成。
/core-service=management/access=authorization
as role-mapping
元素。
过程 11.16. 查看组角色分配配置
- 使用
read-children-names
操作来获取配置角色的完整列表:/core-service=management/access=authorization:read-children-names(child-type=role-mapping)
[standalone@localhost:9999 access=authorization] :read-children-names(child-type=role-mapping) { "outcome" => "success", "result" => [ "ADMINISTRATOR", "DEPLOYER", "MAINTAINER", "MONITOR", "OPERATOR", "SuperUser" ] }
- 使用指定 role-mapping 的
read-resource
操作来获取某个角色的完整细节:/core-service=management/access=authorization/role-mapping=ROLENAME:read-resource(recursive=true)
[standalone@localhost:9999 access=authorization] ./role-mapping=ADMINISTRATOR:read-resource(recursive=true) { "outcome" => "success", "result" => { "include-all" => false, "exclude" => undefined, "include" => { "user-theboss" => { "name" => "theboss", "realm" => undefined, "type" => "USER" }, "user-harold" => { "name" => "harold", "realm" => undefined, "type" => "USER" }, "group-SysOps" => { "name" => "SysOps", "realm" => undefined, "type" => "GROUP" } } } } [standalone@localhost:9999 access=authorization]
过程 11.17. 添加新的角色
- 使用
add
操作来添加新的角色配置。/core-service=management/access=authorization/role-mapping=ROLENAME:add
[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR:add {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
过程 11.18. 添加包含在角色里的组
- 请使用
add
操作来添加组到角色的包含列表里。/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:add(name=GROUPNAME, type=GROUP)
ROLENAME 是被配置的角色的名称。GROUPNAME 是添加到包含列表里的组的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如group-GROUPNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/include=group-investigators:add(name=investigators, type=GROUP) {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
过程 11.19. 添加角色所排除的组
- 请使用
add
操作来添加组到角色的排除列表里。/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:add(name=GROUPNAME, type=GROUP)
ROLENAME 是被配置的角色的名称。GROUPNAME 是添加到包含列表里的组的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如group-GROUPNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/exclude=group-supervisors:add(name=supervisors, type=USER) {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
过程 11.20. 删除组的角色包含配置
- 请使用
remove
操作来删除这个条目。/core-service=management/access=authorization/role-mapping=ROLENAME/include=ALIAS:remove
ROLENAME 是被配置的角色的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如group-GROUPNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/include=group-investigators:remove {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
从包含列表里删除组并不会从系统删除这个组,也不能保证角色不会被分配给这个组。这个角色仍可能分配给组里的用户。
过程 11.21. 删除组的角色排除配置
- 请使用
remove
操作来删除这个条目。/core-service=management/access=authorization/role-mapping=ROLENAME/exclude=ALIAS:remove
ROLENAME 是被配置的角色的名称。ALIAS
是这个映射的唯一名称。红帽推荐你对别名使用命名规则,如group-GROUPNAME
。[standalone@localhost:9999 access=authorization] ./role-mapping=AUDITOR/exclude=group-supervisors:remove {"outcome" => "success"} [standalone@localhost:9999 access=authorization]
从排除列表里删除组并不会从系统删除这个组,也不能保证角色被分配给这个组。这个角色仍可能根据组成员资格被排除。
11.9.7. 关于用 LDAP 进行授权和组加载
<authorization> <ldap connection="..."> <username-to-dn> <!-- OPTIONAL --> <!-- Only one of the following. --> <username-is-dn /> <username-filter base-dn="..." recursive="..." user-dn-attribute="..." attribute="..." /> <advanced-filter base-dn="..." recursive="..." user-dn-attribute="..." filter="..." /> </username-to-dn> <group-search group-name="..." iterative="..." group-dn-attribute="..." group-name-attribute="..." > <!-- One of the following --> <group-to-principal base-dn="..." recursive="..." search-by="..."> <membership-filter principal-attribute="..." /> </group-to-principal> <principal-to-group group-attribute="..." /> </group-search> </ldap> </authorization>
重要
username-to-dn
username-to-dn
元素是关于它的定义的,只有下列两者都为 true 才要求定义这个元素:
- 验证步骤不是通过 LDAP 进行的。
- 组搜索在搜索过程中使用标识名。
- 1:1 username-to-dn
- 这个是最基本的配置形式,用于指定远程用户输入的用户名实际上是标识名。
<username-to-dn> <username-is-dn /> </username-to-dn>
因为这是定义的 1:1 的映射,所以没有其他可能的配置。 - username-filter
- 下一个选项和上面验证步骤描述的选项非常类似,它简单地按照提供的用户名进行搜索。
<username-to-dn> <username-filter base-dn="dc=people,dc=harold,dc=example,dc=com" recursive="false" attribute="sn" user-dn-attribute="dn" /> </username-to-dn>
可以在这里设置的属性是:base-dn
: 开始搜索的上下文的标识名。recursive
:搜索是否将扩展到子上下文。默认值为false
。attribute
:根据提供的用户名尝试和匹配的用户条目的属性。默认值为uid
。user-dn-attribute
:为获得用户标识名而读取的属性。默认值为dn
。
- advanced-filter
- 这个最后的选项指定了高级过滤器,和验证部分一样,这是使用自定义过滤器来定位用户标识名的机会。
<username-to-dn> <advanced-filter base-dn="dc=people,dc=harold,dc=example,dc=com" recursive="false" filter="sAMAccountName={0}" user-dn-attribute="dn" /> </username-to-dn>
对应 username-filter 的属性的默认值都是一样的,这里不再列出。新的属性是:filter
:用于搜索用户条目的过滤器,用户名将在占位符{0}
里替换。
重要
XML 格式必须保持有效,定义过滤器来确保特殊字符(如&
)的正确格式。例如,对于&
字符是&
。
组搜索
例 11.1. Principal to Group - LDIF 示例。
TestUserOne
,它是 GroupOne
的成员,而 GroupOne
也是 GroupFive
的成员。通过属性 memberOf
展示了组成员资格,它被设置为用户(或组)所属的组的标识名。
memberOf
的属性集,每个都对应该用户所属的组。
dn: uid=TestUserOne,ou=users,dc=principal-to-group,dc=example,dc=org objectClass: extensibleObject objectClass: top objectClass: groupMember objectClass: inetOrgPerson objectClass: uidObject objectClass: person objectClass: organizationalPerson cn: Test User One sn: Test User One uid: TestUserOne distinguishedName: uid=TestUserOne,ou=users,dc=principal-to-group,dc=example,dc=org memberOf: uid=GroupOne,ou=groups,dc=principal-to-group,dc=example,dc=org memberOf: uid=Slashy/Group,ou=groups,dc=principal-to-group,dc=example,dc=org userPassword:: e1NTSEF9WFpURzhLVjc4WVZBQUJNbEI3Ym96UVAva0RTNlFNWUpLOTdTMUE9PQ== dn: uid=GroupOne,ou=groups,dc=principal-to-group,dc=example,dc=org objectClass: extensibleObject objectClass: top objectClass: groupMember objectClass: group objectClass: uidObject uid: GroupOne distinguishedName: uid=GroupOne,ou=groups,dc=principal-to-group,dc=example,dc=org memberOf: uid=GroupFive,ou=subgroups,ou=groups,dc=principal-to-group,dc=example,dc=org dn: uid=GroupFive,ou=subgroups,ou=groups,dc=principal-to-group,dc=example,dc=org objectClass: extensibleObject objectClass: top objectClass: groupMember objectClass: group objectClass: uidObject uid: GroupFive distinguishedName: uid=GroupFive,ou=subgroups,ou=groups,dc=principal-to-group,dc=example,dc=org
例 11.2. Group to Principal - LDIF 示例
TestUserOne
,它是 GroupOne
的成员(反之也是 GroupFive
的成员)- 然而在这个例子里,它是一个用于交叉引用的组到用户的属性 uniqueMember
。
dn: uid=TestUserOne,ou=users,dc=group-to-principal,dc=example,dc=org objectClass: top objectClass: inetOrgPerson objectClass: uidObject objectClass: person objectClass: organizationalPerson cn: Test User One sn: Test User One uid: TestUserOne userPassword:: e1NTSEF9SjR0OTRDR1ltaHc1VVZQOEJvbXhUYjl1dkFVd1lQTmRLSEdzaWc9PQ== dn: uid=GroupOne,ou=groups,dc=group-to-principal,dc=example,dc=org objectClass: top objectClass: groupOfUniqueNames objectClass: uidObject cn: Group One uid: GroupOne uniqueMember: uid=TestUserOne,ou=users,dc=group-to-principal,dc=example,dc=org dn: uid=GroupFive,ou=subgroups,ou=groups,dc=group-to-principal,dc=example,dc=org objectClass: top objectClass: groupOfUniqueNames objectClass: uidObject cn: Group Five uid: GroupFive uniqueMember: uid=TestUserFive,ou=users,dc=group-to-principal,dc=example,dc=org uniqueMember: uid=GroupOne,ou=groups,dc=group-to-principal,dc=example,dc=org
通用组搜索
<group-search group-name="..." iterative="..." group-dn-attribute="..." group-name-attribute="..." > ... </group-search>
group-name
:这个属性用来指定用于作为用户所属组列表返回的组名的格式。这可以是组名的简单格式或者是组的标识名,如果标识名是必需的,那这个属性可以设置为DISTINGUISHED_NAME
。默认值是SIMPLE
。iterative
:这个属性用来指定在确定用户所属的组之后是否应该根据组所属的组迭代地进行搜索。如果启用了迭代搜索,那么我们将继续搜索,直到到达不是成员的组或检测到循环。它的默认值为false
。
重要
group-dn-attribute
:组条目上的哪个属性是其标识名。默认为dn
。group-name-attribute
:组条目上的哪个属性是其简单名。默认为uid
。
例 11.3. Principal to Group 配置示例
memberOf
。
<authorization> <ldap connection="LocalLdap"> <username-to-dn> <username-filter base-dn="ou=users,dc=principal-to-group,dc=example,dc=org" recursive="false" attribute="uid" user-dn-attribute="dn" /> </username-to-dn> <group-search group-name="SIMPLE" iterative="true" group-dn-attribute="dn" group-name-attribute="uid"> <principal-to-group group-attribute="memberOf" /> </group-search> </ldap> </authorization>
principal-to-group
元素。
group-attribute
:
例 11.4. Group to Principal 配置示例
<authorization> <ldap connection="LocalLdap"> <username-to-dn> <username-filter base-dn="ou=users,dc=group-to-principal,dc=example,dc=org" recursive="false" attribute="uid" user-dn-attribute="dn" /> </username-to-dn> <group-search group-name="SIMPLE" iterative="true" group-dn-attribute="dn" group-name-attribute="uid"> <group-to-principal base-dn="ou=groups,dc=group-to-principal,dc=example,dc=org" recursive="true" search-by="DISTINGUISHED_NAME"> <membership-filter principal-attribute="uniqueMember" /> </group-to-principal> </group-search> </ldap> </authorization>
group-to-principal
元素,这个元素用来定义引用用户条目的组搜索如何只执行,它将设置下列属性:
base-dn
: 开始搜索的上下文的标识名。recursive
:是否搜索子上下文。默认为false
。search-by
:在搜索里使用的角色名称的格式。有效值是SIMPLE
和DISTINGUISHED_NAME
。默认值为DISTINGUISHED_NAME
。
principal-attribute
:引用用户条目的组条目上的属性名称。默认值为member
。
11.9.8. 关于带作用域的角色
- 唯一的名字。
- 基于那些标准角色。
- 是否应用在服务器组或主机上。
- 所限的服务器组或主机的列表。
- 是否自动包括所有用户。默认为 false。
- 作用域为主机的角色
- 作用域为主机的角色将它的权限限制到一个或多个主机。这意味着为相关的
/host=*/
资源树提供了访问权限但其他主机所专有的资源是隐藏的。 - 作用域为服务器组的角色
- 作用域为服务器组的角色限制了该角色的权限到一个或多个服务器组。此外,角色权限将应用于和指定的服务器组相关联的配置集、套接字绑定组、服务器配置和服务器资源。和这个服务器组逻辑上不关联的资源的任何子资源对于用户来说都是不可见的。
11.9.9. 创建带作用域的角色
- 登录到管理控制台
- 点击 Administration 标签页
- 展开左侧的 Access Control 并选择 Role Assignment
- 选择 ROLES 标签页,然后选择里面的 Scoped Roles 标签页。
图 11.7. 在管理控制台里配置带作用域的角色
过程 11.22. 添加新的带作用域的角色
- 登录到管理控制台
- 导航至 Roles 标签页的 Scoped Roles 区域。
- 点击 Add 按钮。Add Scoped Role 对话框将会出现。
图 11.8. Add Scoped Role 对话框
- 指定下列细节:
- Name,新的带作用域的角色的唯一名称。
- Base Role,这个角色的权限所基于的角色。
- Type,这个角色是否将被限于主机或服务器组。
- Scope,这个角色所限于的主机或服务器组列表。可以选择多重条目。
- Include All,这个角色是否自动包含所有的用户。默认为 no。
- 点击 Save 按钮,对话框将关闭且新创建的角色将出现在表里。
过程 11.23. 编辑带作用域的角色
- 登录到管理控制台
- 导航至 Roles 标签页的 Scoped Roles 区域。
- 点击你要编辑的带作用域的角色。这个角色的细节将出现在表下面的 Selection 面板上。
图 11.9. 选择的角色
- 点击 Selection 面板上的 Edit 链接。Selection 面板将进入编辑模式。
图 11.10. 处于编辑模式的 Selection 面板
- 更新你要修改的细节并点击 Save 按钮。Selection 面板将回到之前的状态。Selection 面板和表都会显示最近更新的细节。
过程 11.24. 查看 Scoped Role 成员
- 登录到管理控制台
- 导航至 Roles 标签页的 Scoped Roles 区域。
- 点击表里你要查看成员的带作用域的角色,然后点击 Members 按钮。Members of role 对话框将出现。它将显示这个角色包含或排斥的用户和组。
图 11.11. Role Membership 对话框
- 当你已经完成查看这些信息后请点击 Done 按钮。
过程 11.25. 删除带作用域的角色
重要
- 登录到管理控制台
- 导航至 Roles 标签页的 Scoped Roles 区域。
- 选择表里要删除的带作用域的角色。
- 点击 Remove 按钮。Remove Scoped Role 对话框将出现。
- 点击 Confirm 按钮。对话框将关闭且角色会被删除。
11.10. 配置约束
11.10.1. 配置 Sensitivity 约束
/core-service=management/access=authorization/constraint=sensitivity-classification
。
类别(classification)
。这些类别被分组为类型(types)
。有 39 种类别被分组成 13 个类型。
write-attribute
操作来设置 configured-requires-read
、configured-requires-write
或 configured-requires-addressable
属性。要使该类型的操作成为敏感的,请将其设置为 false
。在默认情况下,它们不会被设置而使用 default-requires-read
、default-requires-write
和default-requires-addressable
的值。一旦配置的属性被设置,它将替代默认值。默认值不能被修改。
例 11.5. 使读取系统属性成为敏感性操作
[domain@localhost:9999 /] cd /core-service=management/access=authorization/constraint=sensitivity-classification/type=core/classification=system-property [domain@localhost:9999 classification=system-property] :write-attribute(name=configured-requires-read, value=true) { "outcome" => "success", "result" => undefined, "server-groups" => {"main-server-group" => {"host" => {"master" => { "server-one" => {"response" => {"outcome" => "success"}}, "server-two" => {"response" => {"outcome" => "success"}} }}}} } [domain@localhost:9999 classification=system-property] :read-resource { "outcome" => "success", "result" => { "configured-requires-addressable" => undefined, "configured-requires-read" => true, "configured-requires-write" => undefined, "default-requires-addressable" => false, "default-requires-read" => false, "default-requires-write" => true, "applies-to" => { "/host=master/system-property=*" => undefined, "/host=master/core-service=platform-mbean/type=runtime" => undefined, "/server-group=*/system-property=*" => undefined, "/host=master/server-config=*/system-property=*" => undefined, "/host=master" => undefined, "/system-property=*" => undefined, "/" => undefined } } } [domain@localhost:9999 classification=system-property]
表 11.2. Sensitivity 约束配置结果
值 | requires-read | requires-write | requires-addressable |
---|---|---|---|
true
|
读操作是敏感的。
只有 Auditor, Administrator 和 SuperUser 可以读。
|
写操作是敏感的。
只有 Administrator 和 SuperUser 可以写
|
寻址(Addressing)是敏感的。
只有 Auditor, Administrator 和 SuperUser 可以寻址。
|
false
|
读操作是非敏感的。
任何管理用户都可以读。
|
写操作是非敏感的。
只有 Maintainer, Administrator 和 SuperUser 可以写。如果这个约束是一个应用程序资源的话,Deployers 也可以写。
|
寻址(Addressing)是非敏感的。
任何管理用户都可以寻址。
|
11.10.2. 配置应用程序资源约束
/core-service=management/access=authorization/constraint=application-classification/
里的管理模型。
类别(classification)
。这些类别被分组为类型(types)
。有 14 种类别被分组成 8 个类型。每个类别都有一个 applies-to
元素,它是一个类别配置应用的资源路径模式的列表。
core
。Core 包含部署、部署重叠和部署操作。
write-attribute
操作来设置 configured-application attribute
为 true
。要禁用应用程序资源,请设置这个属性为 false
。在默认情况下,这些属性没被设置且使用了 default-application
属性的值。这个默认值不能被修改。
例 11.6. 启用 logger-profile 应用程序资源归类
[domain@localhost:9999 /] cd /core-service=management/access=authorization/constraint=application-classification/type=logging/classification=logging-profile [domain@localhost:9999 classification=logging-profile] :write-attribute(name=configured-application, value=true) { "outcome" => "success", "result" => undefined, "server-groups" => {"main-server-group" => {"host" => {"master" => { "server-one" => {"response" => {"outcome" => "success"}}, "server-two" => {"response" => {"outcome" => "success"}} }}}} } [domain@localhost:9999 classification=logging-profile] :read-resource { "outcome" => "success", "result" => { "configured-application" => true, "default-application" => false, "applies-to" => {"/profile=*/subsystem=logging/logging-profile=*" => undefined} } } [domain@localhost:9999 classification=logging-profile]
重要
11.10.3. 配置 Vault 表达式约束
/core-service=management/access=authorization/constraint=vault-expression
上的管理模型里。
write-attribute
操作来设置 configured-requires-write
和 configured-requires-read
的属性为 true
或 false
。在默认情况下,它们不会被设置而使用 default-requires-read
和 default-requires-write
的值。默认值不能被修改。
例 11.7. 使写入 Vault 表示成为非敏感操作
[domain@localhost:9999 /] cd /core-service=management/access=authorization/constraint=vault-expression [domain@localhost:9999 constraint=vault-expression] :write-attribute(name=configured-requires-write, value=false) { "outcome" => "success", "result" => undefined, "server-groups" => {"main-server-group" => {"host" => {"master" => { "server-one" => {"response" => {"outcome" => "success"}}, "server-two" => {"response" => {"outcome" => "success"}} }}}} } [domain@localhost:9999 constraint=vault-expression] :read-resource { "outcome" => "success", "result" => { "configured-requires-read" => undefined, "configured-requires-write" => false, "default-requires-read" => true, "default-requires-write" => true } } [domain@localhost:9999 constraint=vault-expression]
表 11.3. Vault 表达式约束配置结果
值 | requires-read | requires-write |
---|---|---|
true
|
读操作是敏感的。
只有 Auditor, Administrator 和 SuperUser 可以读。
|
写操作是敏感的。
只有 Administrator 和 SuperUser 可以写。
|
false
|
读操作是不敏感的。
所有管理用户都可以读。
|
写操作是不敏感的。
Monitor, Administrator 和 SuperUser 都可以写。如果 Vault 表达式是一个应用程序资源的话,Deployers 也可以写。
|
11.11. 约束引用
11.11.1. 应用程序资源约束引用
类型:core
- 类别:deployment-overlay
- 默认值:true
PATH 属性 操作 /deployment-overlay=*/deployment=*/upload-deployment-stream, full-replace-deployment, upload-deployment-url, upload-deployment-bytes
类型:datasources
- 类别:datasource
- 默认值:false
PATH 属性 操作 /deployment=*/subdeployment=*/subsystem=datasources/data-source=*/subsystem=datasources/data-source=*/subsystem=datasources/data-source=ExampleDS/deployment=*/subsystem=datasources/data-source=*
- Classification: jdbc-driver
- 默认值:false
PATH 属性 操作 /subsystem=datasources/jdbc-driver=*
- 类别:xa-data-source
- 默认值:false
PATH 属性 操作 /subsystem=datasources/xa-data-source=*/deployment=*/subsystem=datasources/xa-data-source=*/deployment=*/subdeployment=*/subsystem=datasources/xa-data-source=*
类型:logging
- 类别:logger
- 默认值:false
PATH 属性 操作 /subsystem=logging/logger=*/subsystem=logging/logging-profile=*/logger=*
- 类别:logging-profile
- 默认值:false
PATH 属性 操作 /subsystem=logging/logging-profile=*
类型:mail
- 类别:mail-session
- 默认值:false
PATH 属性 操作 /subsystem=mail/mail-session=*
类型:naming
- 类别:binding
- 默认值:false
PATH 属性 操作 /subsystem=naming/binding=*
类型:resource-adapters
- 类别:resource-adapters
- 默认值:false
PATH 属性 操作 /subsystem=resource-adapters/resource-adapter=*
类型:security
- 类别:security-domain
- 默认值:false
PATH 属性 操作 /subsystem=security/security-domain=*
11.11.2. 安全约束引用
类型:core
- 类别:access-control
- requires-addressable: true
- requires-read: true
- requires-write: true
PATH 属性 操作 /core-service=management/access=authorization/subsystem=jmxnon-core-mbean-sensitivity
- 类别:credential
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=mail/mail-session=*/server=pop3username , password/subsystem=mail/mail-session=*/server=imapusername, password/subsystem=datasources/xa-data-source=*user-name, recovery-username, password, recovery-password/subsystem=mail/mail-session=*/custom=*username, password/subsystem=datasources/data-source=*"user-name, password/subsystem=remoting/remote-outbound-connection=*"username/subsystem=mail/mail-session=*/server=smtpusername , password/subsystem=web/connector=*/configuration=sslkey-alias, password/subsystem=resource-adapters/resource-adapter=*/connection-definitions=*"recovery-username, recovery-password
- 类别:domain-controller
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作
- 类别:domain-names
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作
- 类别:extensions
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /extension=*
- 类别:jvm
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=platform-mbean/type=runtimeinput-arguments, boot-class-path, class-path, boot-class-path-supported, library-path
- 类别:management-interfaces
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=management/management-interface=native-interface/core-service=management/management-interface=http-interface
- 类别:module-loading
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=module-loading
- 类别:patching
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=patching/addon=*/core-service=patching/layer=*"/core-service=patching
- 类别:read-whole-config
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /read-config-as-xml
- 类别:security-domain
- requires-addressable: true
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=security/security-domain=*
- 类别:security-domain-ref
- requires-addressable: true
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=datasources/xa-data-source=*security-domain/subsystem=datasources/data-source=*security-domain/subsystem=ejb3default-security-domain/subsystem=resource-adapters/resource-adapter=*/connection-definitions=*security-domain, recovery-security-domain, security-application, security-domain-and-application
- 类别:security-realm
- requires-addressable: true
- requires-read: true
- requires-write: true
PATH 属性 操作 /core-service=management/security-realm=*
- 类别:security-realm-ref
- requires-addressable: true
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=remoting/connector=*security-realm/core-service=management/management-interface=native-interfacesecurity-realm/core-service=management/management-interface=http-interfacesecurity-realm/subsystem=remoting/remote-outbound-connection=*security-realm
- 类别:security-vault
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=vault
- 类别:service-container
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=service-container
- 类别:snapshots
- requires-addressable: false
- requires-read: false
- requires-write: false
PATH 属性 操作 /take-snapshot, list-snapshots, delete-snapshot
- 类别:socket-binding-ref
- requires-addressable: false
- requires-read: false
- requires-write: false
PATH 属性 操作 /subsystem=mail/mail-session=*/server=pop3outbound-socket-binding-ref/subsystem=mail/mail-session=*/server=imapoutbound-socket-binding-ref/subsystem=remoting/connector=*socket-binding/subsystem=web/connector=*socket-binding/subsystem=remoting/local-outbound-connection=*outbound-socket-binding-ref/socket-binding-group=*/local-destination-outbound-socket-binding=*socket-binding-ref/subsystem=remoting/remote-outbound-connection=*outbound-socket-binding-ref/subsystem=mail/mail-session=*/server=smtpoutbound-socket-binding-ref/subsystem=transactionsprocess-id-socket-binding, status-socket-binding, socket-binding
- 类别:socket-config
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /interface=*resolve-internet-address/core-service=management/management-interface=native-interfaceport, interface, socket-binding/socket-binding-group=*/core-service=management/management-interface=http-interfaceport, secure-port, interface, secure-socket-binding, socket-binding/resolve-internet-address/subsystem=transactionsprocess-id-socket-max-ports
- 类别:system-property
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /core-service=platform-mbean/type=runtimesystem-properties/system-property=*/resolve-expression
类型:datasources
- 类别:data-source-security
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=datasources/xa-data-source=*user-name, security-domain, password/subsystem=datasources/data-source=*user-name, security-domain, password
类型:jdr
- 类别:jdr
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /subsystem=jdrgenerate-jdr-report
类型:jmx
- 类别:jmx
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /subsystem=jmx
类型:mail
- 类别:mail-server-security
- requires-addressable: false
- requires-read: false
- requires-write: true
PATH 属性 操作 /subsystem=mail/mail-session=*/server=pop3username, tls, ssl, password/subsystem=mail/mail-session=*/server=imapusername, tls, ssl, password/subsystem=mail/mail-session=*/custom=*username, tls, ssl, password/subsystem=mail/mail-session=*/server=smtpusername, tls, ssl, password
类型:naming
- 类别:jndi-view
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=namingjndi-view
- 类别:naming-binding
- requires-addressable: false
- requires-read: false
- requires-write: false
PATH 属性 操作 /subsystem=naming/binding=*
类型:remoting
- 类别:remoting-security
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=remoting/connector=*authentication-provider, security-realm/subsystem=remoting/remote-outbound-connection=*username, security-realm/subsystem=remoting/connector=*/security=sasl
类型:resource-adapters
- Classification: resource-adapter-security
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=resource-adapters/resource-adapter=*/connection-definitions=*security-domain, recovery-username, recovery-security-domain, security-application, security-domain-and-application, recovery-password
类型:security
- 类别:misc-security
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=securitydeep-copy-subject-mode
类型:web
- 类别:web-access-log
- requires-addressable: false
- requires-read: false
- requires-write: false
PATH 属性 操作 /subsystem=web/virtual-server=*/configuration=access-log
- 类别:web-connector
- requires-addressable: false
- requires-read: false
- requires-write: false
PATH 属性 操作 /subsystem=web/connector=*
- 类别:web-ssl
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=web/connector=*/configuration=ssl
- 类别:web-sso
- requires-addressable: false
- requires-read: true
- requires-write: true
PATH 属性 操作 /subsystem=web/virtual-server=*/configuration=sso
- 类别:web-valve
- requires-addressable: false
- requires-read: false
- requires-write: false
PATH 属性 操作 /subsystem=web/valve=*
第 12 章 事务子系统的配置
12.1. JTS 事务
12.1.1. 为 JTS 事务配置 ORB
注意
full
和 full-ha
配置集。在独立服务器里,你可以使用 standalone-full.xml
或 standalone-full-ha.xml
配置。
过程 12.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
部分。
例 12.1. 启用安全拦截器
/profile=full/subsystem=jacorb/:write-attribute(name=security,value=on)
例 12.2. 启用 JTS 里的 ORB
/profile=full/subsystem=jacorb/:write-attribute(name=transactions,value=on)
例 12.3. 在 JacORB 子系统里启用事务
/profile=full/subsystem=jacorb/:write-attribute(name=transactions,value=on)
例 12.4. 在事务子系统里启用 JTS
/subsystem=transactions:write-attribute(name=jts,value=true)
12.1.2. JMS 配置
12.1.2.1. 对 HornetQ 配置属性的引用
read-resource
操作开放可配置或可查看的属性。
例 12.5. 示例
[standalone@localhost:9999 /] /subsystem=messaging/hornetq-server=default:read-resource
表 12.1. HornetQ 属性
属性 | 示例值 | 类型 |
---|---|---|
allow-failback | true | BOOLEAN |
async-connection-execution-enabled | true | BOOLEAN |
backup | false | BOOLEAN |
cluster-password | somethingsecure | STRING |
mask-password | true | BOOLEAN |
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
的值必须比发往服务器的消息大小要大,否则服务器无法存储这个消息。
第 13 章 Web、HTTP 连接器和 HTTP 群集
13.1. 配置 mod_cluster 工作节点
mod_cluster 工作节点(Worker Node)由一个 JBoss EAP 服务器组成。这个服务器可以是受管域服务器组的一部分,或者是一个独立服务器。在 JBoss EAP 里会有一个单独的进程运行,它管理群集里的所有节点。它被称为主节点。关于工作节点的更多概念,请参考《红帽 JBoss EAP 6.1 管理和配置指南》里的『工作节点』章节。关于 HTTPD 负载平衡的概述,请参考 《JBoss EAP 6.1 管理和配置指南》里的『HTTP 连接器概述』章节。
mod_cluster
子系统配置一次。要配置 mod_cluster
子系统,请参考《管理和配置指南》里的『配置 mod_cluster 子系统』。每个工作节点都是独立配置的,所以你可以为每个要加入群集的节点重复这个步骤。
工作节点配置
- 如果你使用了独立服务器,它必须以
standalone-ha
配置集启动。 - 如果你使用受管域,你的服务器组必须使用
ha
或full-ha
配置集,以及ha-sockets
或full-ha-sockets
套接字绑定组。JBoss EAP 6 附带满足这些要求的启用了群集的服务器组other-server-group
。
注意
/profile=full-ha
。
过程 13.1. 配置工作节点
配置网络接口。
在默认情况下,网络接口都是127.0.0.1
。每个容纳独立服务器或服务器组里的一个或多个服务器的物理主机的接口都需要进行配置以使用其他服务器可以看到的公共 IP 地址。要修改 JBoss EAP 6 主机的 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/bin/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
。你可以在本指南的『敏感字符串的密码阀』里找到更多信息:第 10.11.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
.
- 保存文件并退出。
重启服务器。
从主机现在将以主机名为用户名以及加密的字符串为密码来向主服务器进行验证。
你的独立服务器,或者位于受管域的服务器组里的服务器,现在已被配置为 mod_cluster 工作节点。如果你部署一个群集应用程序,它的会话会被复制到所有的群集节点以用于失效切换,且它可以从外部的 HTTPD 服务器或负载平衡器接受请求。在默认情况下,群集的每个节点都可以用自动发现来发现其他节点。要配置自动发现和 mod_cluster
子系统的其他专有设置,请参考《管理和配置指南》里的『配置 mod_cluster 子系统』章节。要配置 Apache HTTPD 服务器,请参考《管理和配置指南》里的『将外部 HTTPD 用作 JBoss EAP 应用程序的 Web 前端』章节。
第 14 章 安装补丁
14.1. 关于补丁和升级
14.2. 关于补丁机制
- 异步更新(Asynchronous update):作为一次性的补丁,它在现有产品的常规更新周期之外发布。它可能包含安全补丁、红帽全球支持服务(GSS)提供的用以修复特定问题的其他一次性补丁。
- 计划中的更新(Planned update):它包括现有产品的累积补丁、小版本、次要版本或主要版本升级。累积补丁包括为该产品版本开发的所有异步更新。
重要
14.3. 订阅补丁邮件列表(Patch Mailing List)
红帽的 JBoss 团队维护了一个用于中间件安全通知的邮件列表。本节涵盖订阅这个列表所需的步骤。
前提条件
- 无
过程 14.1. 订阅 JBoss Watch List
- 点击下列链接进入 JBoss Watch 邮件列表页面:JBoss Watch Mailing List。
- 在 Subscribing to Jboss-watch-list 部分输入你的电子邮件地址。
- [你可能也想输入你的名字和密码。这是可选的,但我们不推荐这么做。]
- 点击 Subscribe 按钮启动订阅过程。
- 你可以访问 JBoss Watch Mailing List Archives 来浏览邮件列表的归档。
在确认你的电子邮件账号之后,你将订阅 JBoss 补丁邮件列表来接收安全相关的通知。
14.4. 以 ZIP 形式安装补丁
14.4.1. patch
命令
patch
命令用来将下载的 ZIP 补丁应用到单个 JBoss EAP 6 服务器实例。它无法在整个受管域里自动应用补丁,而只能对其中单独的服务器实例应用补丁。
重要
patch
命令进行更新。关于更新用 RPM 安装的 JBoss EAP 6 服务器,请参考 第 14.5 节 “以 RPM 形式安装补丁”。
注意
patch
只能用于 JBoss EAP 6.2 和更高版本。对于 6.2 版以前的补丁,你应该参考相关版本的文档:https://access.redhat.com/site/documentation/。
patch
命令可以给出安装的补丁状态的基本信息,并提供立即回滚应用程序补丁的途径。
patch
工具将检查它根据用户修改而更新的模块和其他杂项文件。如果检测到用户的修改,且没有指定 conflict-handling 开关,patch
工具将中止操作并发出冲突警告。这个警告将包括一个有冲突的模块和其他文件的列表。要完成这个操作,patch
命令必须带有指定如何解决冲突的开关来重新运行:要么保留用户的修改,要么进行覆盖。
表 14.1. patch
命令的参数和开关
参数或开关 | 描述 |
---|---|
apply | 应用补丁。 |
--override-all | 如果有冲突,补丁操作将覆盖任何用户所作的修改。 |
--override-modules | 如果任何已修改的模块有冲突,这将用补丁操作里的内容覆盖这些修改。 |
--override=path(,path) | 只用于指定的杂项文件,它经用补丁操作里的文件覆盖有冲突的已修改的文件。 |
--preserve=path(,path) | 只用于指定的杂项文件,它保存有冲突的已修改的文件。 |
info | 返回当前安装的补丁的信息。 |
rollback | 回滚应用程序的补丁。 |
--reset-configuration=TRUE|FALSE | 进行回滚必须设置的选项,它指定是否将回复服务器配置文件作为回滚操作的一部分。 |
14.4.2. 用 patch
命令安装 ZIP 形式的补丁
这个任务描述了如何使用 patch
命令以 ZIP 方式来安装 JBoss EAP 6。
重要
patch
命令是 JBoss EAP 6.2 里添加的功能。对于 6.2 之前的版本,安装 ZIP 格式的补丁的过程是不一样的,你可以参考相关版本的文档:https://access.redhat.com/site/documentation/。
前提条件
- 对红帽客户门户的有效访问和订阅。
- 对以 ZIP 形式安装的 JBoss 产品的当前订阅。
- 对要更新的服务器实例的管理 CLI 的访问。请参考《管理和配置指南》里的 《登陆管理 CLI》。
过程 14.2. 使用 patch
命令应用 ZIP 补丁到 JBoss EAP 6 服务器实例。
警告
- 从红帽客户入口 https://access.redhat.com/downloads/ 下载补丁 ZIP 文件。
- 在管理 CLI 里,用下列命令及补丁文件的合适路径来应用补丁:
[standalone@localhost:9999 /]
patch apply /path/to/downloaded-patch.zip
如果在试图应用补丁时有冲突,patch
根据将显示警告。关于使用命令开关重新运行命令以解决冲突的信息,请参考 第 14.4.1 节 “patch
命令”。 - 重启 JBoss EAP 6 服务器实例以使补丁生效:
[standalone@localhost:9999 /]
shutdown --restart=true
JBoss EAP 6 服务器实例更新了最新的补丁。
14.4.3. 回滚用 patch
命令安装 ZIP 形式的补丁
这个任务描述了如何使用 patch
命令回滚以 ZIP 方式来安装了补丁的 JBoss EAP 6。
警告
patch
命令回滚应用程序补丁的目的不是作为一个普通的写在功能。它的目的是在安装补丁后出现意外后果时立即使用。
重要
patch
命令是 JBoss EAP 6.2 里添加的功能。对于 6.2 之前的版本,回滚 ZIP 格式的补丁的过程是不一样的,你可以参考相关版本的文档:https://access.redhat.com/site/documentation/。
前提条件
- 之前使用
patch
命令应用的补丁。 - 对服务器实例的管理 CLI 的访问。请参考《管理和配置指南》里的 《登陆管理 CLI》。
过程 14.3. 使用 patch
命令从 JBoss EAP 6 服务器实例回滚 ZIP 补丁。
- 在管理 CLI 里,用
patch info
命令来找到要回滚的补丁的 ID。- 对于累积补丁,补丁 ID 是
patch info
输出里的第一个cumulative-patch-id
的值。 - 一次性安全补丁或程序错误修复补丁的 ID 会显示为
patch info
输出里的第一个patches
的值,而最近应用的一次性补丁将首先列出。
- 在管理 CLI 里,用前面步骤里得到的补丁 ID 来进行回滚。
警告
请小心使用--reset-configuration
开关。如果设置为TRUE
,补丁回滚过程也会将 JBoss EAP 6 服务器配置文件回复到应用补丁之前的状态。在应用补丁之后对配置文件的修改都会丢失。如果为FALSE
,服务器配置文件不会被回滚。在这种情况下,服务器可能在回滚后无法启动,因为补丁可能已经修改了配置文件(如命名空间)而导致它不再有效,你需要手动进行修复。[standalone@localhost:9999 /]
patch rollback PATCH_ID --reset-configuration=TRUE
如果在试图回滚补丁时有冲突,patch
根据将显示警告。关于使用命令开关重新运行命令以解决冲突的信息,请参考 第 14.4.1 节 “patch
命令”。 - 重启 JBoss EAP 6 服务器实例以使补丁回滚生效:
[standalone@localhost:9999 /]
shutdown --restart=true
JBoss EAP 6 服务器实例已回滚了补丁及服务器配置文件(可选)。
14.5. 以 RPM 形式安装补丁
JBoss 补丁以两种形式发布:ZIP(用于所有产品)和 RPM(用于产品的子集)。本节描述了使用 RPM 形式安装补丁的步骤。
前提条件
- 对红帽网络的有效订阅。
- 对以 RPM 形式安装的 JBoss 产品的当前订阅。
过程 14.4. 通过 RPM 方式对 JBoss 产品应用补丁
yum
来安装。
警告
- 通过订阅 JBoss Watch 邮件列表或浏览 JBoss Watch 邮件列表归档来获得安全补丁的通知。
- 阅读安全补丁的勘误并确认它可以应用于你的 JBoss 产品。
- 如果安全补丁适用于你的 JBoss 产品,请用这个链接从红帽客户门户下载包含在勘误里的 PRM 软件包。
- 请使用
来安装补丁。yum update
重要
在更新 RPM 安装时,你的 JBoss 产品将用发布的所有 RPM 补丁进行累积更新。
JBoss 产品用 RPM 软件包方式更新了最新的补丁。
14.6. JBoss 安全补丁的严重性和影响级别
表 14.2. JBoss 安全补丁的严重性级别
严重性 | 描述 |
---|---|
严重(Critical) |
这个级别是容易被未授权的远程攻击者利用的漏洞,它可能导致系统破解(任意代码执行)而无需用户干预。这些漏洞易受蠕虫病毒利用。要求经验证的远程用户、本地用户或不太可能的配置的漏洞不会被归类于严重(Critical)影响级别。
|
重要(Important) |
这个级别的漏洞可以轻易地破解资源的机密性、完整性或能力。这些漏洞允许本地用户获取权限,允许未验证的远程用户查看本应该被验证保护的资源、执行任意的代码,或者允许本地或远程用户导致服务拒绝问题。
|
中等(Moderate) |
这个级别的漏洞可能更难被利用,但仍然会导致资源的机密性、完整性或能力某种程度的破解。这些漏洞可能产生严重或重要的影响,但根据技术评估,会较不容易被利用或影响不太可能的配置。
|
低(Low) |
其他具有安全性影响的漏洞都归类于这个级别。这些漏洞在不太可能的情况下才会被利用,或者即使被利用也只会造成最小的后果。
|
例 14.1. CVSS v2 影响分数
C:N/I:P/A:C
14.7. 管理部署在 JBoss EAP 上的应用程序内部捆绑的依赖关系的更新
工具和数据源
- JBoss 补丁邮件列表
- 订阅 JBoss 补丁邮件列表将让你知晓 JBoss 产品里已修复的安全漏洞,允许你检查所部署的应用程序是否捆绑了受影响组件的易受攻击的版本。
- 用于绑定的组建的安全顾问页面。
- 许多开源都有自己的安全顾问页面。例如,Struts 2 是常用的带有许多已知安全问题、且不属于 JBoss EAP 安装的一部分的组件。Struts 2 项目维护着一个上游安全顾问页面,如果你的应用程序捆绑了 Struts 2,你应该注意这个页面。许多商用的组件也维护着安全顾问页面。
- 经常扫描你部署的应用程序里已知的漏洞
- 你可以使用几个常用的商业工具。红帽员工开发了一个名为 Victims 的开源工具,但并不为此提供支持和保障。Victims 为几个构建和集成工具提供插件,它自动扫描应用程序里捆绑的已知的易受攻击的依赖关系。这些插件可用于 Maven、Ant 和 Jenkins。关于 Victims 工具的更多信息,请参考 https://victi.ms/about.html。
部分 III. 保证应用程序的安全
第 15 章 应用程序的安全性
15.1. 关于应用程序的安全性
15.2. 启用/禁用基于描述符的属性替换
jboss-as-ee_1_1.xsd
引入了对描述符属性替换的有限控制。本节内容涵盖了配置基于描述符的属性替换所需的步骤。
前提条件
- 启动 JBoss EAP 实例。
- 启动管理 CLI。
- 如果设置为
true
,属性替换将被启用。 - 如果设置为
false
,属性替换将被禁用。
过程 15.1. jboss-descriptor-property-replacement
jboss-descriptor-property-replacement
用于在下列描述符里启用或禁用属性替换:
jboss-ejb3.xml
jboss-app.xml
jboss-web.xml
*-jms.xml
*-ds.xml
jboss-descriptor-property-replacement
的默认值是 true
。
- 在管理 CLI 里,运行下列命令来确定
jboss-descriptor-property-replacement
的值:/subsystem=ee:read-attribute(name="jboss-descriptor-property-replacement")
- 运行下列命令来配置其行为:
/subsystem=ee:write-attribute(name="jboss-descriptor-property-replacement",value=VALUE)
过程 15.2. spec-descriptor-property-replacement
spec-descriptor-property-replacement
用于在下列描述符里启用或禁用属性替换:
ejb-jar.xml
persistence.xml
spec-descriptor-property-replacement
的默认值是 false
。
- 在管理 CLI 里,运行下列命令来确认
spec-descriptor-property-replacement
的值:/subsystem=ee:read-attribute(name="spec-descriptor-property-replacement")
- 运行下列命令来配置其行为:
/subsystem=ee:write-attribute(name="spec-descriptor-property-replacement",value=VALUE)
成功地配置了基于描述符的属性替换标记。
15.3. 数据源安全性
15.3.1. 关于数据源安全性
例 15.1. 安全域示例
<security> <security-domain>mySecurityDomain</security-domain> </security>
例 15.2. 密码阀示例
<security> <user-name>admin</user-name> <password>${VAULT::ds_ExampleDS::password::N2NhZDYzOTMtNWE0OS00ZGQ0LWE4MmEtMWNlMDMyNDdmNmI2TElORV9CUkVBS3ZhdWx0}</password> </security>
15.4. EJB 应用程序的安全性
15.4.1. 安全标识符
15.4.1.1. 关于 EJB 的安全标识符
<security-identity>
标记。它表示其他 EJB 在调用组件上的方法时必须使用的标识符。
<use-caller-identity>
标签,而第二种情况则使用 <run-as>
标签。
15.4.1.2. 设置 EJB 的安全标识符
例 15.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>
例 15.4. 设置 EJB 的安全标识符为特定的角色
<security-identity>
标签内部的 <run-as>
和 <role-name>
标签。
<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>
元素。
15.4.2. EJB 方法权限
15.4.2.1. 关于 EJB 方法权限(EJB Method Permission)
<method-permisison>
元素声明。这个声明设置了被允许调用 EJB 的接口方法的角色。你可以为下列组合指定权限:
- 命名 EJB 的所有 home 和 component 接口方法
- 命名 EJB 的 home 或 component 接口的一个指定的方法
- 具有重载名的一系列方法里的一个指定的方法
15.4.2.2. 使用 EJB Method Permission
<method-permission>
元素定义了被允许访问 <method>
定义的 EJB 方法的逻辑角色。下面的几个例子演示了 XML 的语法。其中多个 method permission 语句可能会出现并具有累积的效应。<method-permission>
元素是 <ejb-jar>
描述符里 <assembly-descriptor>
元素的一个子元素。
例 15.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>
例 15.6. 允许角色访问 EJB 的某个方法,并限制可以传递哪些方法参数:
<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>
例 15.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>
例 15.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>
例 15.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>
15.4.3. EJB 安全注解
15.4.3.1. 关于 EJB 安全注解
- @DeclareRoles
- 声明哪些角色是可用的。
- @RolesAllowed, @PermitAll, @DenyAll
- 指定哪些方法权限是被允许的。关于方法权限的更多信息,请参考 第 15.4.2.1 节 “关于 EJB 方法权限(EJB Method Permission)”。
- @RunAs
- 配置组件的传播的安全标识符。
15.4.3.2. 使用 EJB 安全注解
你可以使用 XML 描述符或注解来控制哪些安全角色能够调用你的 EJB 里的方法。关于使用 XML 描述符的更多信息,请参考 第 15.4.2.2 节 “使用 EJB Method Permission”。
控制 EJB 的安全权限的注解
- @DeclareRoles
- 使用 @DeclareRoles 来定义针对哪些安全角色检查权限。如果没有使用 @DeclareRoles,这个列表将自动根据 @RolesAllowed 注解进行构建。
- @SecurityDomain
- 指定用于 EJB 的安全域。如果 EJB 的授权用
@RolesAllowed
进行注解,授权将只在 EJB 用安全域注解时才会应用。 - @RolesAllowed, @PermitAll, @DenyAll
- 使用 @RolesAllowed 来列出哪些角色别允许访问某个或某些方法。使用 @PermitAll 或 @DenyAll 来允许或拒绝所有的角色使用某个或某些方法。
- @RunAs
- 使用 @RunAs 来指定总是以之运行的某个角色或方法。
例 15.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 GoodbyeAdmin(String msg) { return "See you later, " + msg; } }
WelcomeEveryone
。 GoodBye
方法在进行调用时以 tempemployee
角色运行。只有 admin
角色可以访问方法 GoodbyeAdmin
,以及其他任何没有使用安全性注解的的方法。
15.4.4. 对 EJB 的远程访问
15.4.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)。
15.4.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
方法。
15.4.4.3. 关于远程服务器检测
15.4.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 EAP 6 组件,如 EJB、ORB、JMS 提供者,在默认情况下都使用安全的接口。
警告
工作者线程池是处理来自 Remoting 连接器的任务的线程组。它是一个单一的元素 <worker-thread-pool>
,并使用几个属性。如果你遇到网络超时、线程用尽或需要限制内存使用,你可以调整这些属性。其推荐值取决于特定的环境。更多的信息,请联系红帽全球支持服务。
表 15.1. 工作者线程池属性
属性 | 描述 | 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 6 的子系统使用。对自定义连接器的元素和属性的设置取决于你的应用程序,更多的信息请联系红帽全球支持服务。
表 15.2. 连接器属性
属性 | 描述 | CLI 命令 |
---|---|---|
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 EAP 6 安装里
ApplicationRealm 是可用的。
| /profile=default/subsystem=remoting/connector=remoting-connector/:write-attribute(name=security-realm,value=ApplicationRealm)
|
表 15.3. 连接器元素
属性 | 描述 | CLI 命令 |
---|---|---|
sasl |
用于简单验证和安全层(Simple Authentication and Security Layer,SASL)验证机制的封装元素
| N/A
|
属性 |
包含一个或多个
<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
属性以用于授权。
表 15.4. 转出连接的元素
属性 | 描述 | 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 计算强度值的列表,以降序排列。
|
/profile=default/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-anonymous,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) |
属性 |
包含一个或多个
<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) |
例 15.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="http://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 和多点传送的自动检测
15.4.4.5. 对远程 EJB 客户使用安全区
- 添加新的安全区到域控制器或独立服务器里。
- 添加下列参数到位于应用程序的 classpath 上的
jboss-ejb-client.properties
文件里。这个例子假设文件里的其他参数引用的连接是default
。remote.connection.default.username=appuser remote.connection.default.password=apppassword
- 在域或独立服务器上创建一个使用新的安全区的自定义远程连接器。
- 部署 EJB 到使用带有自定义远程连接器的服务器组里,如果你使用的不是受管域则部署到独立服务器里。
15.4.4.6. 添加新的安全区
运行管理 CLI。
运行jboss-cli.sh
或jboss-cli.bat
命令并连接服务器。创建新的安全区。
运行下列命令在域控制器或独立服务器上创建一个名为MyDomainRealm
的安全区。/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)
你的新安全区已被创建了。当你添加用户和角色到这个新的安全区时,信息将被存储在默认安全区外的一个单独的文件里。你可以用自己的应用程序或过程来管理这个新的文件。
15.4.4.7. 添加用户到安全区里
运行
add-user.sh
或add-user.bat
命令。打开一个终端并进入EAP_HOME/bin/
目录。如果你运行的是红帽企业版 LInux 或其他类 Unix 系统,请运行add-user.sh
。如果你运行的是 Microsoft Windows 服务器,则请运行add-user.bat
。选择是否添加管理用户或应用程序用户。
对于这个过程,输入b
来添加应用程序用户。选择用户所添加至的安全区。
在默认的情况下,唯一可用的安全区是ApplicationRealm
。如果你已经添加了一个自定义区,你可以输入它的名称。在提示时输入用户名、密码和角色。
在提示时输入想要的用户名、密码和可选角色。输入yes
确认选择或no
取消修改。所作修改将被写入到安全区的每个属性文件里。
15.4.4.8. 关于使用 SLL 加密的远程 EJB 访问
15.5. JAX-RS 应用程序的安全性
15.5.1. 为 RESTEasy JAX-RS Web 服务启用基于角色的安全性
RESTEasy 支持 JAX-RS 方法上的 @RolesAllowed、@PermitAll 和 @DenyAll 注解。然而,在默认情况下它并不承认这些注解。请遵循这些步骤来配置 web.xml
文件并启用基于角色的安全性。
警告
过程 15.3. 为 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>
这个应用程序里已经启用了基于角色的安全性并定义了一系列角色。
例 15.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>
15.5.2. 使用注解保护 JAX-RS Web 服务
这个主题涵盖了使用支持的安全注解来保护 JAX-RS Web 服务的安全。
过程 15.4. 使用支持的安全注解保护 JAX-RS Web 服务
- 启用基于角色的安全性。更多信息请参考:第 15.5.1 节 “为 RESTEasy JAX-RS Web 服务启用基于角色的安全性”。
- 添加安全注解到 JAX-RS Web 服务里。RESTEasy 支持下列注解:
- @RolesAllowed
- 定义哪个角色可以访问这个方法。所有的角色都应该在
web.xml
文件里定义。 - @PermitAll
- 允许
web.xml
文件里定义的所有角色访问这个方法。 - @DenyAll
- 拒绝所有对这个方法的访问。
第 16 章 单点登录(SSO)
16.1. 关于 Web 应用程序的单点登录
单点登录(Single Sign On,SSO)允许到某个资源的验证可以授权对其他资源的访问。
非群集的 SSO 限制分享授权信息至相同虚拟机上的应用程序。此外,它在主机出现故障时无弹性可言。而群集 SSO 数据可以在多个虚拟主机里的应用程序间共享,对失效切换有一定弹性。而且,群集 SSO 可以从负载平衡器接收请求。
如果资源是未受保护的,用户根本不会被验证。如果用户访问了受保护的资源,用户将被验证。
SSO 的限制
- 不能在第三方边界传播数据
- SSO 只能在部署在 JBoss EAP 6 容器里的应用程序间使用。
- 只能用于容器管理的验证
- 你必须在应用程序
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 应用程序里一致。所有的安全集成必须接受相同的凭证(如用户名和密码)。
16.2. 关于 Web 应用程序的群集单点登录
jboss-web.xml
里完成的。
- Apache Tomcat ClusteredSingleSignOn
- Apache Tomcat IDPWebBrowserSSOValve
- SPNEGO-based SSO provided by PicketLink
16.3. 选择正确的 SSO 实现
如果你的机构已经使用了基于 Kerberos 的验证和授权系统,如 Microsoft Active Directory,你可以使用相同的系统来透明地验证运行在 JBoss EAP 6 里的应用程序。
如果你需要在运行在相同服务器组或实例里的应用程序间传播安全信息,你可以使用非群集的 SSO。这只要在应用程序的 jboss-web.xml
描述符里配置库(valve)就可以了。
如果你需要在运行在跨多个 JBoss EAP 6 实例的群集环境里的应用程序间传播安全信息,你可以使用群集的 SSO 库(Valve)。这只要在应用程序的 jboss-web.xml
描述符里进行配置就可以了。
16.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。请注意,这些命令修改了受管域的ha
配置集。对于独立服务器,你可以修改这些命令来使用其他的配置集,或者去掉命令行的/profile=ha
部分。例 16.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
,表示子系统存在。否则,你需要添加它。例 16.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)
例 16.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 没有在你的配置里出现。例 16.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
参数,它们控制持久数据的群集复制。
例 16.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>
表 16.1. SSO 配置选项
选项 | 描述 |
---|---|
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()
方法在程序里使会话失效。
16.5. 关于 Kerberos
16.6. 关于 SPNEGO
16.7. 关于 Microsoft Active Directory
- 轻量级目录访问协议(Lightweight Directory Access Protocol,LDAP),存储用户、主机、密码和其他资源的信息。
- Kerberos,提供网络上的安全验证。
- 域名服务(Domain Name Service,DNS)提供 IP 地址和网络上主机和其他设备的名称之间的映射。
16.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 的类的映射。
表 16.2. 登录模块代码和类名
简单名称 | 类名 | 目的 |
---|---|---|
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.
过程 16.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="UsersRoles" 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 功能。
第 17 章 应用程序里基于角色的安全性
17.1. 关于安全性扩展架构
这个架构的第一部分是 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 和其他加密的用例。
关于安全性架构的更多信息以及实践示例,请参考 第 17.3 节 “关于 Java 认证和授权服务(JAAS)”。
17.2. Java 认证和授权服务(JAAS)
17.3. 关于 Java 认证和授权服务(JAAS)
服务器组(受管域里)和服务器(独立服务器里)包含了安全域的配置。安全域包括合并验证、授权、映射和审计模块的信息以及配置细节。应用程序在 jboss-web.xml
里通过名字指定它需要哪个安全域。
应用程序专有的配置出现在一个或多个下列的四个文件里。
表 17.1. 应用程序专有的配置文件
文件 | 描述 |
---|---|
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 6 里,容器端的组件是 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
安全域。下面的图表展示了这些步骤,我们在后面将进行解释。
图 17.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 对象相关联。
17.4. 在应用程序里使用安全域
要在应用程序里使用安全域,首先你必须通过服务器配置文件或应用程序的描述符文件配置安全域。然后你必须添加必要的注解到使用安全域的 EJB。这个主题涵盖了在应用程序里使用安全域所需的步骤。
过程 17.1. 配置你的应用程序以使用安全域
定义安全域
你可以在服务器的配置文件或应用程序的描述符里定义安全域。在服务器的配置文件里配置安全域
安全域是在服务器配置文件的security
子系统里配置的。如果 JBoss EAP 6 实例运行在受管域里,配置文件应该是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,你可以在红帽的客户门户找到这些例子。
17.5. 在 Servlet 里使用基于角色的安全性
jboss-web.xml
里指定的安全域处理的。
在你在 servlet 里使用基于角色的安全性之前,用来验证和授权访问的安全域需要在 JBoss EAP 6 容器里进行配置。
过程 17.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-constraint> <security-role> <role-name>eap_admin</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> </login-config>
你需要指定验证方法,它可以是BASIC, FORM, DIGEST, CLIENT-CERT, SPNEGO.
。这个例子使用了BASIC
验证。在 WAR 的
jboss-web.xml
里指定安全域添加安全域到 WAR 的jboss-web.xml
以连接 servlet 到配置好的安全域,它知道如何根据安区性约束验证和授权 principal。下面的例子使用名为acme_domain
的安全域。<jboss-web> ... <security-domain>acme_domain</security-domain> ... </jboss-web>
例 17.1. 配置了基于角色的安全性的 web.xml
示例
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Use Role-Based Security In Servlets</display-name> <welcome-file-list> <welcome-file>/index.jsp</welcome-file> </welcome-file-list> <servlet-mapping> <servlet-name>DisplayOpResult</servlet-name> <url-pattern>/DisplayOpResult</url-pattern> </servlet-mapping> <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-constraint> <security-role> <role-name>eap_admin</role-name> </security-role> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>
17.6. 在应用程序里使用第三方的验证系统
注意
context.xml
里,它现在直接在 jboss-web.xml
描述符里进行配置。context.xml
现在已被忽略了。
例 17.2. 基本的验证阀
<jboss-web> <valve> <class-name>org.jboss.security.negotiation.NegotiationAuthenticator</class-name> </valve> </jboss-web>
例 17.3. 带有头部属性集的自定义阀
<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 代码可以作为例子参考。
例 17.4. 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; } }
第 18 章 移植
18.1. 应用程序安全性的修改
在以前的 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
。
附录 A. 参考
A.1. 包括的验证模块
Code
名称里的 Role
。
Code
值或完整名称(软件包限定)来引用模块。
验证模块
表 A.1. 登录模块
代码 | 分类 | 描述 |
---|---|---|
客户端 | 分类 | 这个登录模块的目的是当 JBoss EAP 6 充当客户时建立调用者标识符和凭证。它不应该作为用于实际的服务器验证的安全域的一部分。 |
Remoting | N/A | Remoting 登录模块用于检查当前验证的的请求是否是从远程连接接收的,如果是则使用在验证过程中创建的标识符并和当前请求相关联。如果这个请求不是通过远程连接到达的,这个模块将不会做任何事情,并允许基于 JAAS 的登录继续,进入下一个模块。 |
RealmDirect | N/A | 如果当前的请求没有发生在 Remoting 登录模块里,RealmDirect 登录模块将使用安全区来进行验证,然后使用这个区来加载用户的角色。在默认情况下,这个等录模块假定要使用的区名为 ApplicationRealm,但也可以用其他名称覆盖。这个方法的好处是所有的存储配置都可以在区里完成,只需把安全域委托给安全区就可以了。 |
表 A.2. 客户模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
multi-threaded | true 或 false
| false
|
如果每个线程都有自己的 principal 和凭证存储,请将其设置为 true。false 则指定虚拟机里的所有线程都共享系统的标识符和凭证。
|
password-stacking
| useFirstPass 或 false
| false
|
设置为 useFirstPass 表示这个登录模块应该寻找存储在 LoginContext 里的信息以用作标识符。当堆积这个登录模块和其他模块时可以使用这个选项。
|
restore-login-identity
| true 或 false
| false
|
如果在 login() 方法的开始遇到的标识符和凭证在 logout() 被调用后要重新存储,请将其设置为 true。
|
表 A.3. Certificate
代码 | Certificate
|
分类 | org.jboss.security.auth.spi.BaseCertLoginModule
|
描述 |
这个登录模块的目的是基于
X509 Certificates 验证用户。其中一个用例是 web 应用程序的 CLIENT-CERT 验证。
|
表 A.4. Certificate
Module Options
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
securityDomain
| 串 |
无
|
具有持有信任证书的信任库的 JSSE 配置的安全域的名称。
|
verifier
| 分类 |
无
|
用户登录证书检验的
org.jboss.security.auth.certs.X509CertificateVerifier 的类名。
|
表 A.5. CertificateUsers
代码 | CertificateUsers
|
分类 | org.jboss.security.auth.spi.UsersRolesLoginModule
|
描述 |
使用属性资源。第一个映射用户名和密码,第二个映射用户名和角色。
|
表 A.6. CertificateUsers
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
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 选项来传递的。
|
表 A.7. CertificateRoles
代码 | CertificateRoles
|
分类 | org.jboss.security.auth.spi.CertRolesLoginModule
|
描述 |
这个登录模块扩展了 Certificate 登录模块以从属性文件添加角色映射能力。它使用和 Certificate 登录模块相同的所有选项,并添加了如下选项。
|
表 A.8. CertificateRoles
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
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 文件里的角色组分隔符的字符。
|
表 A.9. Database
代码 | Database |
分类 | org.jboss.security.auth.spi.DatabaseServerLoginModule
|
描述 |
支持验证和角色映射的基于 JDBC 的登录模块。这基于具有下列定义的两个逻辑表。
|
表 A.10. Database
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
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 。
|
表 A.11. DatabaseCertificate
代码 | DatabaseCertificate
|
分类 | org.jboss.security.auth.spi.DatabaseCertLoginModule
|
描述 |
这个登录模块扩展了 Certificate 登录模块以从数据库表添加角色映射能力。它使用和 Certificate 登录模块相同的所有选项,并添加了如下选项。
|
表 A.12. DatabaseCertificate
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
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 事务是否应该被暂停。
|
表 A.13. Identity
代码 | Identity
|
分类 | org.jboss.security.auth.spi.IdentityLoginModule
|
描述 |
关联这个模块选项里指定的 principal 和任何针对这个模块验证的主题。所使用的 Principal 类的类型是
org.jboss.security.SimplePrincipal 。如果没有指定 principal 选项,那使用的名称是 guest 。
|
表 A.14. Identity
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
principal
| 字符串 | guest
|
用于 principal 的名称。
|
roles
| 用逗号隔开的字符串的列表 |
无
|
将分配给主题的用逗号隔开的角色列表。
|
表 A.15. Ldap
代码 | Ldap
|
分类 | org.jboss.security.auth.spi.LdapLoginModule
|
描述 |
当用户名和密码存储在可通过 JNDI LDAP 供应商访问的 LDAP 服务器上时进行的验证。许多选项不是必需的,因为它们可由 LDAP 供应商或系统环境来决定。
|
表 A.16. 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 的区别是搜索用户角色的上下文可能对于每个用户都是唯一的。
|
roleAttributeID
| 属性 | roles
|
包含用户角色的属性的名称。
|
roleAttributeIsDN
| true 或 false
| false
| roleAttributeID 是否包含角色对象的全限定 DN。如果为 false,角色名将从上下文名称的 roleNameAttributeId 属性值里获取。某些目录模式,如 Microsoft Active Directory,要求这个属性的值为 true 。
|
roleNameAttributeID
| 属性 | group
|
包含角色名称的
roleCtxDN 上下文里的属性的名称。如果 roleAttributeIsDN 属性为 true ,这个属性将被用来查找角色对象的 name 属性。
|
uidAttributeID
| 属性 | uid
| UserRolesAttributeDN 里对应用户 ID 的属性的名称。它被用来定位用户角色。
|
matchOnUserDN
| true 或 false
| false
|
对用户角色搜索是否应该匹配用户的全限定 DN 或只是用户名而已。如果为
true ,完整的用户 DN 将作为匹配值。如果为 false ,则只使用用户名来匹配 uidAttributeName 属性。
|
allowEmptyPasswords
| true 或 false
| true
|
是否允许空的密码。多数 LDAP 服务器将空密码视同匿名登录尝试。要拒绝空密码,请将它设置为 false。
|
表 A.17. LdapExtended
代码 | LdapExtended
|
分类 | org.jboss.security.auth.spi.LdapExtLoginModule
|
描述 |
另外的一个使用搜索来定位绑定用户和关联角色的 LDAP 登录模块实现。角色队列递归地解析 DN 来导航分层的角色结构。它使用和 LDAP 模块相同的
java.naming 选项以及下列 LDAP 模块没有的选项。
这个验证以两步进行:
|
表 A.18. LdapExtended
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
baseCtxDN
| 全限定的 DN |
无
|
开始用户搜索的顶层上下文的固定 DN。
|
bindDN
| 全限定的 DN |
无
|
用户和角色查询里用来绑定 LDAP 服务器的 DN。这个 DN 需要读取和搜索
baseCtxDN 和 rolesCtxDN 值上的权限。
|
bindCredential
| 字符串,可以进行加密。 |
无
| bindDN 的密码以明文存储,或者用 EXT 命令从外部夹在。这个密码可以用 Vault 机制进行加密。你可以使用下列格式:
参考下面的主题里关于加密敏感字符串的内容: 第 10.11.2 节 “创建一个 Java 密钥库来存储敏感信息”
|
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。
|
表 A.19. RoleMapping
代码 | RoleMapping
|
分类 | org.jboss.security.auth.spi.RoleMappingLoginModule
|
描述 |
映射作为验证过程的最终结果的角色到声明式角色。当你添加这个模块到安全域里时,它必须标记为
optional 。
|
表 A.20. RoleMapping
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
rolesProperties
| 属性文件或资源的全限定文件路径 | roles.properties
|
映射角色到替代角色的属性文件或资源的全限定文件路径。其格式是
original_role=role1,role2,role3 。
|
replaceRole
| true 或 false
| false
|
是否添加当前的角色,或者用映射的角色替换当前的角色。设为
true 则进行替换。
|
表 A.21. RunAs
代码 | RunAs
|
分类 | Class: org.jboss.security.auth.spi.RunAsLoginModule
|
描述 |
这是一个 Helper 模块,它在验证的登录阶段将
run as 角色推入栈,并在提交或中止阶段从栈里弹出 run as 角色。这个登录模块为其他必须访问安全资源以执行验证的登录模块(如访问安全 EJB 的登录模块)提供了一个角色。在要求 run as 角色的登录模块建立之前,你必须先配置好 RunAsLoginModule 。
|
表 A.22. RunAs
选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
roleName
| 角色名称 | nobody
|
在登录阶段用作
run as 角色的角色的名称。
|
表 A.23. Simple
代码 | Simple
|
分类 | org.jboss.security.auth.spi.SimpleServerLoginModule
|
描述 |
用于测试目的的快速设置安全性的模块。它实现了下列简单的算法:
|
Simple
模块选项
Simple
模块没有选项。
表 A.24. ConfiguredIdentity
代码 | ConfiguredIdentity
|
分类 | org.picketbox.datasource.security.ConfiguredIdentityLoginModule
|
描述 |
关联这个模块选项里指定的 principal 和任何针对这个模块验证的主题。所使用的 Principal 类的类型是
org.jboss.security.SimplePrincipal 。
|
表 A.25. ConfiguredIdentity
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
principal
| principal 的名称。 | none
|
将和针对这个模块验证的任何主题关联的 principal。
|
表 A.26. SecureIdentity
代码 | SecureIdentity
|
分类 | org.picketbox.datasource.security.SecureIdentityLoginModule
|
描述 |
提供这个模块只是为了和之前的系统兼容。它允许你加密密码并和静态 principal 一起使用这个密码。如果你的应用程序使用了
SecureIdentity ,请考虑使用密码库机制。
|
表 A.27. SecureIdentity
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
username
| 串 | 无 | 用于验证的用户名。 |
password
| 加密的字符串 | 无 |
用于验证的密码。要加密这个密码,请在命令行直接使用这个模块。
将这个命令的运行结果粘贴到模块选项的 value 字段。
|
managedConnectionFactoryName
| JCA 资源 | 无 |
数据源的 JCA 连接工厂的名称。
|
表 A.28. PropertiesUsers
代码 | PropertiesUsers
|
分类 | org.jboss.security.auth.spi.PropertiesUsersLoginModule
|
描述 |
使用一个属性文件来存储用户名和密码。它没有提供授权(角色映射)。这个模块只适合于测试用途。
|
表 A.29. SimpleUsers
代码 | SimpleUsers
|
分类 | org.jboss.security.auth.spi.SimpleUsersLoginModule
|
描述 |
这个登录模块在一个 Java 属性文件里保存了用户名和明文密码。这只是用于测试目的,不适合用于产品环境里。
|
表 A.30. SimpleUsers
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
username
| 串 | 无 | 用于验证的用户名。 |
password
| 串 | 无 | 用于验证的明文密码。 |
表 A.31. LdapUsers
代码 | LdapUsers
|
分类 | org.jboss.security.auth.spi.LdapUsersLoginModule
|
描述 | LdapUsers 模块被 ExtendedLDAP 和 AdvancedLdap 模块取代。
|
表 A.32. Kerberos
代码 | 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 里找到。这个模块需要和另外一个处理验证和角色映射的模块配对。
|
表 A.33. Kerberos
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
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 在两个验证阶段都完成后从共享内存里清除用户名和密码。
|
表 A.34. SPNEGOUsers
代码 | SPNEGOUsers
|
分类 | org.jboss.security.negotiation.spnego.SPNEGOLoginModule
|
描述 |
允许在 Microsoft Active Directory 服务器或其他支持 SPNEGO 的环境里进行 SPNEGO 验证。SPNEGO 也可以包含 Kerberos 凭证。这个模块需要和另外一个处理验证和角色映射的模块配对。
|
表 A.35. SPNEGO
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
storeKey
| true 或 false
| false
|
是否保存密钥。
|
useKeyTab
| true 或 false
| false
|
是否使用密钥表。
|
principal
|
代表 Kerberos 验证的 principal 的字符串。
|
无
|
用于验证的 principal 的名称。
|
keyTab
|
代表 keytab 的文件或资源。
| none
|
密钥表的位置。
|
doNotPrompt
| true 或 false
| false
|
是否提示输入密码。
|
debug
| true 或 false
| false
|
是否记录更冗余的信息以用于调试。
|
表 A.36. AdvancedLdap
代码 | AdvancedLdap |
分类 | org.jboss.security.negotiation.AdvancedLdapLoginModule
|
描述 |
提供额外功能的模块,如 SASL 和对 JAAS 安全域的使用。
|
表 A.37. AdvancedLdap
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
bindAuthentication
|
串
|
无
|
用于绑定到目录服务器的 SASL 验证的类型。
|
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 里的角色。
|
表 A.38. AdvancedADLdap
代码 | AdvancedADLdap |
分类 | org.jboss.security.negotiation.AdvancedADLoginModule
|
描述 |
这个模块扩展了
AdvancedLdap 登录模块,并添加额外的和 Microsoft Active Directory 相关的参数。
|
表 A.39. UsersRoles
代码 | UsersRoles |
分类 | org.jboss.security.auth.spi.UsersRolesLoginModul
|
描述 |
支持存储在两个不同属性文件里的多个用户和角色的简单登录模块。
|
表 A.40. UsersRoles
模块选项
选项 | 类型 | 默认 | 描述 |
---|---|---|---|
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。
|
验证模块是 javax.security.auth.spi.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
来满足要求。
表 A.41. 常用的顶级属性
属性 | 描述 |
---|---|
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>
的子元素。
表 A.42. 注解配置元素
属性 | 描述 |
---|---|
class-name |
注解的类名
|
servlet-security |
代表了 servlet 安全性的元素,如
@ServletSecurity 。
|
run-as |
代表了 run-as 信息的元素,如
@RunAs 。
|
multi-part |
代表了 multi-part 信息的元素,如
@MultiPart 。
|
描述 listener。下表列出了 <listener>
的子元素。
表 A.43. Listener 配置元素
属性 | 描述 |
---|---|
class-name |
Listener 的类名
|
listener-type | condition 元素的列表,表示添加哪种 listener 到应用程序的 Context 里。有效值为:
|
module |
包含 listener 类的模块的名称。
|
param |
包含两个子元素的参数:
<param-name> 和 <param-value> 。
|
描述应用程序的库。它包含和 <listener> 相同的配置元素。
A.6. EJB 安全参数引用
表 A.44. 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. 安全标识符示例
<session>
里。
<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. 修订记录
修订历史 | |||
---|---|---|---|
修订 1.0.0-1 | Wed Jul 02 2014 | CS Builder Robot | |
|