2012-10-18 84 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>