2013-05-31 95 views
1

我想從不同的EJB服務器調用遠程EJB。我在OpenEJB上部署了遠程EJB,然後我將從Glassfish HTTPServlet中調用它們。我知道在本地EJB上,我可以執行@EJB批註,但我希望用戶從Glassfish servlet「認證」遠程OpenEJB服務器。來自HttpServlet的遠程EJB

上OpenEJB的:

//OpenEJB server at 192.168.10.12 
public class AdminManager { 
    @RolesAllowed("admin") 
    public void test() { 
     System.out.println("Admin called this method"); 
    } 
} 

Glassfish的Servlet的

//Glassfish servlet at 192.168.10.10 
public class AdminManage extends HttpServlet { 

    @Override 
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
      Properties p = new Properties(); 
      p.put("java.naming.factory.initial", "org.apache.openejb.client.RemoteInitialContextFactory"); 
      p.put("java.naming.provider.url", "ejbd://192.168.10.12:4201"); 
      // user and pass optional 

     String userName = req.getSession().getAttribute("username"); 
     String password = req.getSession().getAttribute("password"); 
      p.put("java.naming.security.principal", userName); 
      p.put("java.naming.security.credentials", "password); 

      final InitialContext ctx = new InitialContext(p); 

      final AdminManagerRemote myBean = (MyBean) ctx.lookup("AdminManagerRemote"); 
      try { 
       myBean.test(); 
      } catch(Exception epx) { 
       resp.sendRedirect(resp.encodeRedirectURL("/login")); 
      } 
    } 
} 

好這似乎是一個解決方案,但這個不適合我 「好」 的解決方案。 每次對openejb進行身份驗證都是這樣的;

String userName = req.getSession().getAttribute("username"); 
    String password = req.getSession().getAttribute("password"); 
    p.put("java.naming.security.principal", userName); 
    p.put("java.naming.security.credentials", "password); 

而且代碼不乾淨。 我希望用戶只驗證一次並調用ejb方法。 有沒有更好的解決方案呢?

我可以將Glassfish HTTP身份驗證與遠程openEJB身份驗證結合嗎? 我的意思是當用戶對Glassfish HTTP服務器進行身份驗證時,我也想要openEJB身份驗證。 這真的讓我發瘋。什麼解決方案是好的,以逃避spagetti代碼?

回答

0

兩個想法:

  1. 身份驗證OpenEJB的,當用戶登錄到Glassfish的,存儲在用戶會話EJB的存根和以後重新使用它。我擔心你需要爲serialization of the stub(所謂的句柄)實現一些EJB 2.x接口來工作。

  2. 在存儲EJB存根的地方實現一個高速緩存。如果給定用戶名/密碼的存根位於緩存中,則重用該存根,否則進行認證。緩存是一個靜態對象,它可以用Guava的CacheBuilder創建。這違反了規範(你不應該使用static來共享servlet之間的信息),但是由於它是一個緩存,所以這不是什麼大問題。它甚至可以在集羣中工作。

0

你可以嘗試將服務定位器模式,以消除代碼冗餘&隱藏了底層細節創建初始上下文的&複雜性,JNDI查找等

可以緩存遠端home接口EJBHome &然後在需要時重新使用它。

可以參考Core J2EE Patterns - Service Locator文檔瞭解更多詳情。

0

Kerberos呢?有人知道Kerberos解決方案嗎? 使用TGS登錄到所有遠程服務器。

但在互聯網上沒有樣本。 它很難用openldap安裝Kerberos。