gpt4 book ai didi

java - 无法在自定义 LoginModule 中获取密码

转载 作者:搜寻专家 更新时间:2023-11-01 03:56:44 27 4
gpt4 key购买 nike

我正在尝试为 Wildfly 8.0.0.CR1 编写我自己的名为 CustomLoginModule 的登录模块,它在 standalone.xml 中注册了一个安全域:

<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="com.someExample.CustomLoginModule" flag="required">
<module-option name="password-stacking" value="useFirstPass"/>
</login-module>
</authentication>
</security-domain>

在我的远程客户端中,我使用以下 jboss-ejb-client.properties:

endpoint.name=client-endpoint  
remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false
remote.connections=default
remote.connection.default.host=[...]
remote.connection.default.port=[...]
remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false
remote.connection.default.username=myUserName
remote.connection.default.password=abcde

在客户端获取 InitialContext 如下所示:

Properties props = new Properties();  
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
InitialContext ctx = new InitialContext(props);

基本上这工作正常,当通过远程接口(interface)访问 EJB 时调用我的登录模块,该接口(interface)用正确的 @SecurityDomain 注释。

在登录模块中,我可以使用回调或传递给 initialize 方法的 sharedState 读取用户名。但是我无法获得提供的密码(在这个例子中我希望得到字符串 abcde)。

我已经尝试了几种方法来获取密码。通过回调(就像我在 JBoss 5 上所做的那样),通过给定的 sharedState,......即使我从 org.jboss.security.auth.spi.UsernamePasswordLoginModule 派生或者使用JBoss-Quickstart例子,我看不到客户端设置的密码。相反,我总是将以下字符串作为密码 org.jboss.as.security.remoting.RemotingConnectionCredential@... 返回。

编辑:这是我的 LoginModule 的代码(或至少它的一个版本):

import javax.security.auth.callback.*;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

public class CustomLoginModule implements LoginModule
{
private CallbackHandler callbackHandler;

public void initialize(Subject subject, CallbackHandler callbackHandler,
Map<String, ?> sharedState, Map<String, ?> options)
{
this.callbackHandler = callbackHandler;
}

public boolean login() throws LoginException
{
NameCallback namecallback = new NameCallback("Username");
PasswordCallback passwordcallback = new PasswordCallback("Password", false);
CallbackHandler handler = this.callbackHandler;
try {
handler.handle(new Callback[] { namecallback, passwordcallback });
}
catch (Exception e) {
e.printStackTrace();
}
String username = namecallback.getName();
char[] password2 = passwordcallback.getPassword();
String password = new String(password2);
System.out.println(username + " / " + password);
if (username == null || password == null) {
return false;
}
// do authentication...
return true;
}

public boolean commit() throws LoginException
{ ... }

public boolean abort() throws LoginException
{ ... }

public boolean logout() throws LoginException
{ ... }
}

最佳答案

我现在创建了一个小的测试项目来了解如何让它工作。我认为它值得分享。

我们遍历 ClientLoginModule(由 Wildfly 提供)在第一阶段(ApplicationRealm,用于保护远程-联系)。该模块存储凭据(在某处?),之后它们可供我的其他登录模块使用。

<security-realm name="ApplicationRealm">
<authentication>
<jaas name="AppRealmLoopThrough"/>
</authentication>
</security-realm>

当然,这个安全域必须在之后定义:

<security-domain name="AppRealmLoopThrough" cache-type="default">
<authentication>
<login-module code="Client" flag="required">
<module-option name="multi-threaded" value="true"/>
</login-module>
</authentication>
</security-domain>
<security-domain name="other" cache-type="default">
<authentication>
<login-module code="com.someExample.CustomLoginModule" flag="required"/>
</authentication>
</security-domain>

CustomLoginModule(扩展 UsernamePasswordLoginModule)中,我可以执行以下操作来检索用户名和密码:

final String[] usernameAndPassword = getUsernameAndPassword();
System.out.println("received username: " + usernameAndPassword[0] + " and password " + usernameAndPassword[1]);

getUsernameAndPassword()是基类UsernamePasswordLoginModule提供的方法。

当然,安全的 EJB 必须用 @SecurityDomain("other") 注释(或通过部署描述符)才能调用我的 CustomLoginModule

顺便说一句:我知道安全域 other 有一些特殊的含义,不应该用于应用程序 - 这只是为了测试......;)

我试图为此寻找解释时并不是很成功。对我来说,登录模块似乎分两步调用:首先,当 AppRealmLoopThrough 用于 ApplicationRealm 时,它是 http 的安全领域-远程连接器。在此“步骤”中,用户名和密码可用。第二个“步骤”是在容器检查 EJB 权限时调用 CustomLoginModule。在此阶段,默认情况下无法获取密码(如最初尝试的那样)。这听起来合理吗?

关于java - 无法在自定义 LoginModule 中获取密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21475229/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com