2

我有一个 EJB 3.1 应用程序和与该应用程序连接的 java 客户端。我需要创建用户身份验证。

例子:

class LoginBean{

public remoteLogin(String login, String password){
  // create user context with user ID
}
}

class BeanAbc{
  public remoteSecureMethod(){
      // get user context - if no context throw error
      // get user ID/login from user context and do some additional logic..
  }
}

用户凭据存储在数据库中。我正在使用 Glassfish 服务器。如何存储用户上下文?什么是最好的解决方案?有没有简单的框架?

4

3 回答 3

2

基本上(据我所知)EJB 3.1 中的客户端应用程序安全性仍然与 2.x 中的一样,因此您应该找到示例。

您需要设置的内容:

  • 服务器端的 jaas 登录模块(正如您在 Web 应用程序中看到的那样)
  • 确定如何处理身份验证的客户端属性文件
  • 客户端回调,为客户端身份验证过程提供凭据
  • 使用类路径上的属性文件启动客户端

这是 jboss-as 的示例,但我认为您可以将其翻译到其他服务器,因为这个想法是通用的:

# file auth.conf on the client 
adb {
   // jBoss LoginModule
   org.jboss.security.ClientLoginModule  required
   ;
};

这基本上说对于登录上下文adb,客户端登录模块需要成功。此上下文adb链接到服务器端的相应应用程序 jaas 上下文。

在代码中,您像这样设置登录:

CallbackHandler cbh =
    new LoginCallbackHandler(user,pass.toCharArray());
try {
    LoginContext lc = new LoginContext("adb",cbh); 
    lc.login();  // <--- triggers the show in the client
}
catch (LoginException e) {
    System.err.println("Login failed: "+e.getMessage());
}

在 LoginContext 中,您adb从上面的 auth.conf 文件中提供上下文。

LoginCallbackHandler可能看起来像这样:

package de.bsd.adb.client;
import java.io.IOException;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;

public class LoginCallbackHandler implements CallbackHandler {
  private String user;
  private char[] pass;
  // Konstruktor
  LoginCallbackHandler(String username,char[] password) {
    user=username;
    pass=password;
  }
// handle() does the real work and is invoked from the client container
  public void handle(Callback[] callbacks)
    throws IOException, UnsupportedCallbackException
  {
    // Iterate over the call backs
    for (int i =0 ; i< callbacks.length; i++)
    {
      // NameCallback -> pass Login-Name 
      if (callbacks[i] instanceof NameCallback)
      {
        System.out.println("NameCallback");
        NameCallback nc = (NameCallback)callbacks[i];
        nc.setName(user);
      }
      // PasswordCallback -> pass Password
      else if (callbacks[i] instanceof PasswordCallback)
      {
        System.out.println("PasswordCallback");
        PasswordCallback pc =
            (PasswordCallback)callbacks[i];
       pc.setPassword(pass);
      }
      else {  // unknown callback            
         throw new UnsupportedCallbackException(callbacks[i],"Ouch");
     }}}

现在您可以启动您的客户端程序

java -Djava.security.auth.login.config=/path/to/auth.conf -cp bla my.Main
于 2012-10-22T19:57:22.470 回答
1

您绝对应该看看Spring Security,它是 Java EE 应用程序事实上的标准安全框架。即使你一开始只使用框架的一小部分,它也会让你走上正轨,让你根据需要发展(如果你想切换身份验证方法、管理授权等)。

于 2012-10-21T07:14:20.327 回答
0

我想补充@Heiko Rupp 提供的答案 - 他提供的代码将作为独立应用程序运行良好。如果您使用的是应用程序服务器,您应该检查如何使用应用程序服务器配置来配置 JAAS 模块。
例如,在oVirt开源项目中,我们正在使用 Kerberos 登录模块。
我们目前使用的是 JBoss AS 7。
我们通过在 security-domains 部分下定义一个 security-domain 来配置standalone.xml 配置文件 -

 <security-domain name="EngineKerberosAuth">
                    <authentication>
                        <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required"/>
                    </authentication>
                </security-domain>
于 2012-10-24T18:21:38.007 回答