JBoss7:自定义登录模块无法正常工作

时间:2013-08-12 06:58:04

标签: java-ee jboss7.x java-ee-6 ejb-3.1

我正在从JBoss 5.0.1迁移到JBoss 7.2。

我正在使用远程EJB客户端调用EJB。 我必须迁移一个派生自AbstractServerLoginModule

的自定义登录模块

我设法配置JBoss,以便实际调用自定义登录模块。

在自定义登录模块中,我实现了javax.security.auth.callback.NameCallbackjavax.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");

我希望密码以自定义登录模块中的服务器上的纯文本形式到达。那可能吗?我怎样才能做到这一点?

1 个答案:

答案 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"/>