2012-10-18 79 views
2

我有一个EJB 3.1应用程序和Java客户端与此应用程序连接。 我需要创建一个用户认证。EJB 3.1中的简单身份验证

实施例:

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.. 
    } 
} 

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

+3

你正在寻找一个简单的框架是JavaEE本身:-) –

+1

OK,但你可以给我的例子吗?我找到了一些JAAS示例,但始终使用Web应用程序。我没有Web应用程序,但只有Java客户端直接连接到ejb服务器。 – fxuser

+1

我在网上找不到任何好的例子:(请帮忙 – fxuser

回答

1

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

1

基本上(据我所知)在EJB 3.1的客户端应用程序的安全性仍是像在2.x的,所以你应该找到例子。

你需要设置什么:

  • JAAS登录服务器端模块(正如你已经看到了网络应用程序),决定如何处理身份验证
  • 客户端
  • 客户端属性文件回拨,提供凭证的客户端验证过程
  • 使用类路径上的属性文件启动客户端

这对于JBoss,作为一个例子,但我认为你可以转化为其他服务器,这个想法是通用的:

# 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将你给从上面的auth.conf文件的背景下adb

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 
0

我想对@Heiko鲁普提供的答案添加 - 代码他提供的将会独立运行。 如果您使用的是应用程序服务器,则应该检查如何使用应用程序服务器配置来配置JAAS模块。
例如,在oVirt开源项目中,我们使用的是Kerberos登录模块。
我们目前正在使用JBoss AS 7.
我们已经配置了独立。通过在安全域部分定义安全域的XML配置文件 -

<security-domain name="EngineKerberosAuth"> 
        <authentication> 
         <login-module code="com.sun.security.auth.module.Krb5LoginModule" flag="required"/> 
        </authentication> 
       </security-domain>