在 JBoss-5.1.0.GA 应用服务器中,如何保护远程 EJB 不受未经身份验证的主体的影响?配置我的 ejb 安全性后,我仍然可以使用 JNDI 查找访问远程 EJB,而无需传入主体和凭据?这是一个安全风险。本质上,我想禁用远程 EJB 上所有未经身份验证的 JNDI 查找。
这是我的server/conf/login-config.xml配置:
<application-policy name="<my security domain name>">
<authentication>
<login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
<module-option name="dsJndiName">**java:jdbc/<my datasource name>**</module-option>
<module-option name="principalsQuery"><my users query></module-option>
<module-option name="rolesQuery"><my roles query></module-option>
<module-option name="debug">true</module-option>
</login-module>
</authentication>
</application-policy>
这是我的 ejb jar 中的jboss.xml配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC
"-//JBoss//DTD JBOSS 5.0//EN"
"http://www.jboss.org/j2ee/dtd/jboss_5_0.dtd">
<jboss>
<security-domain><my security domain name from login-config></security-domain>
</jboss>
这是我如何进行 JNDI 查找以作为客户端访问我的 bean 注意主体和凭据没有被传递到上下文
Hashtable<String, String> props = new Hashtable<String, String>();
props.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
props.put(Context.URL_PKG_PREFIXES,"org.jboss.naming:org.jnp.interfaces");
props.put(Context.PROVIDER_URL,"jnp://localhost:1099");
//props.put(Context.SECURITY_PRINCIPAL,"");
//props.put(Context.SECURITY_CREDENTIALS,"");
ctx = new InitialContext(props);
ctx.lookup("<earname>/<ejb interface definition>/remote">
问题是什么? 当没有/错误的主体/凭证被传递时,用户被认证为匿名主体,并且可以通过 JNDI 完全访问远程 EJB
我已经尝试解决的问题:
我从我的server/conf/login-config.xml中的所有登录模块中删除了以下行,但它没有效果
<module-option name="unauthenticatedIdentity">anonymous</module-option>
我从server/conf/jboss-service.xml中删除了以下行,认为它会解决问题,但没有效果
<attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
我从默认情况下存在的 login-config.xml 中删除了应用程序策略“client-login”,因为我使用的是 DatabaseLoginModule
我在server/depoly/security/security-policies-jboss-beans.xml中的jboss-ejb-policy和jboss-web-policy正在扩展 login-config.xml 中的 DatabaseLoginModule 策略
我的 ejb 类/接口中没有与安全相关的注释
其他注意事项
我在 Jboss-as-7.1.1.final 中测试了这个场景,我得到EjbAccessException: invalid User这是正确的(你将它添加到 jboss-ejb3.xml 它将通过安全域保护所有 EJB)
<assembly-descriptor> <s:security> <ejb-name>*</ejb-name> <s:security-domain><security domain name here></s:security-domain> </s:security> </assembly-descriptor>
这里的问题不是授权,而是身份验证所有 ejb 安全注释都无济于事
我想要做的是完全阻止匿名主体进行 JNDI 调用
我在 org.jboss.security 上启用了 TRACE 日志记录,我可以看到,每当我调用 JNDI 时,我都会在日志中得到以下命中
Principal: anonymous:callerRunAs=null:callerRunAs=null:ejbRestrictionEnforcement=false:ejbVersion=null]; policyRegistration=org.jboss.security.plugins.JBossPolicyRegistration@1f51a2f;
当我通过 WebAuthetication 使用编程登录时,我已经验证了我的所有配置工作,并且 DatabaseLoginModule 工作正常
即使从数据库传递初始上下文一个有效的主体/凭证,使用匿名主体也表明主体/凭证甚至没有被上下文处理
我可能可以通过@RolesAllowed @DeclareRoles 保护我的EJB ...但就像我提到的那样,这将是授权问题而不是身份验证,而且如果我有很多角色和EJB,就可维护性而言,这不会很好
如何像在 JBoss 7.1.1 中那样自动禁用/防止对整个应用程序进行未经身份验证的匿名 JNDI 查找?我知道我可以将我的应用程序服务器升级为一种解决方案,但我没有选择这样做。这在 Jboss 5.1.0 中应该是可能且容易做到的。但是我到处寻找答案却找不到?谢谢你的帮助。