我正在从JBoss 5.0.1迁移到JBoss 7.2。
我正在使用远程EJB客户端调用EJB。
我必须迁移一个派生自AbstractServerLoginModule
。
我设法配置JBoss,以便实际调用自定义登录模块。
在自定义登录模块中,我实现了javax.security.auth.callback.NameCallback
和javax.security.auth.callback.ObjectCallback
之类的:
NameCallback ncb = new NameCallback("Username:");
PasswordCallback pcb = new PasswordCallback("Password:", false);
try
{
callbackHandler.handle(new Callback[] { ncb, pcb });
}
catch (Exception e)
{
if (e instanceof RuntimeException)
{
throw (RuntimeException) e;
}
return false;
}
String name = ncb.getName();
String pwd = new String(pcb.getPassword());
我看到用户按照我的预期传递给NameCallback
。
但我发现传递给PasswordCallback
的密码始终是"随机值"喜欢" 0299df2c-620a-4ac6-83d3-50daaa65fb90"。
我用来调用服务器的客户端代码如下所示:
Properties clientProp = new Properties();
clientProp.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
clientProp.put("remote.connections", "default");
clientProp.put("remote.connection.default.port", "4447");
clientProp.put("remote.connection.default.host", "localhost");
clientProp.put("remote.connection.default.username", "USER");
clientProp.put("remote.connection.default.password", "PASSWORD");
clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS", "false");
clientProp.put("remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(clientProp);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
final Properties jndiProperties = new Properties();
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
jndiProperties.put("jboss.naming.client.ejb.context", true);
jndiProperties.put(InitialContext.SECURITY_PRINCIPAL, "USER");
jndiProperties.put(InitialContext.SECURITY_CREDENTIALS, "PASSWORD");
我希望密码以自定义登录模块中的服务器上的纯文本形式到达。那可能吗?我怎样才能做到这一点?
答案 0 :(得分:3)
我终于解决了这个问题。
密码设置为随机值的原因是密码永远不会到达服务器。似乎JBoss中的安全实现然后在没有密码传递的情况下将密码设置为随机值。
使用以下客户端代码,密码在登录模块的明文中按预期显示:
final Properties jndiProperties = new Properties();
jndiProperties.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
jndiProperties.put("remote.connections", "one");
jndiProperties.put("remote.connection.one.port", "4447");
jndiProperties.put("remote.connection.one.host", "localhost");
jndiProperties.put("remote.connection.one.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
jndiProperties.put("remote.connection.one.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
jndiProperties.put("remote.clusters", "ejb");
jndiProperties.put("remote.cluster.ejb.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT", "false");
jndiProperties.put("remote.connection.one.username", username);
jndiProperties.put("remote.connection.one.password",password);
jndiProperties.put("remote.cluster.ejb.username", username);
jndiProperties.put("remote.cluster.ejb.password", password);
jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(jndiProperties);
ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
EJBClientContext.setSelector(selector);
final Context context = new InitialContext(jndiProperties);
MessageServieRemote msgService = (MessageServieRemote) context.lookup("ejb:TestEar/TestNopEjb//MessageService!net.jonasbandi.ejbremote.MessageServieRemote");
System.out.println(msgService.getMessage());
重要部分似乎是以下两个属性:
jndiProperties.put("remote.connection.one.connect.options.org.xnio.Options.SASL_POLICY_NOPLAIN TEXT", "false");
jndiProperties.put("remote.connection.one.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS", "JBOSS-LOCAL-USER");
上述第一个属性确保密码以明文形式从客户端传递到服务器。
当您在同一台机器上运行JBoss和EJB客户机时,EJB客户机优化通信并“本机”调用服务器而不是远程远程调用服务器。在我的例子中,这绕过了由remotinng子系统引用的ApplicationRealm上配置的login-module。上述第二个属性不允许此行为,并强制EJB客户端始终使用远程处理,因此不会绕过我的自定义登录模块。
只是为了完成:服务器配置的相关部分(在我的文件standalone-ha.xml
中)看起来像这样:
远程处理子系统引用AppplicationRealm:
<subsystem xmlns="urn:jboss:domain:remoting:1.1">
<connector name="remoting-connector" socket-binding="remoting" security-realm="ApplicationRealm"/>
</subsystem>
ApplicationRealm引用自定义安全域
<security-realm name="ApplicationRealm">
<authentication>
<jaas name="myDomain"/>
</authentication>
<authorization>
<properties path="application-roles.properties" relative-to="jboss.server.config.dir"/>
</authorization>
</security-realm>
自定义安全域配置自定义登录模块:
<security-domain name="myDomain" cache-type="default">
<authentication>
<login-module code="net.jonasbandi.ejbremote.CustomLoginModule" flag="required " module="deployment.TestEar.ear">
<module-option name="password-stacking" value="useFirstPass"/>
<module-option name="realm" value="ApplicationRealm"/>
</login-module>
</authentication>
</security-domain>
请注意,在上述情况下,我将CustomLoginModule部署为我的EAR的一部分,因此必须使用属性module="deployment.TestEar.ear"
。
最后,我将默认安全域设置为自定义安全域:
<default-security-domain value="myDomain"/>