2012-01-05 58 views
3

這不是一個簡單的問題,它僅僅是因爲我正在重新思考我們的架構,以便通過登錄和安全保護我們的EJB 3.0服務。rmi ejb中可重用登錄會話的概念調用

我們在JBoss 5.1上有一個EJB3.0應用程序,它爲SWT客戶端提供讀取和寫入數據的各種服務。要使用服務,客戶端必須使用SpringSecurity在LDAP服務器中查找的有效用戶和密碼進行登錄。 SpringSecurity會生成一個會話標識,該標識將被傳回給客戶端,以便在任何進一步的服務調用中重新使用。

client       server 
    |        | 
    |-> login(user/password)-------->| 
    |        | 
    | <------- sessionId ------------| 
    |        | 
    |-->serviceXy(sessionId,param1)->| 

情況似乎很清楚。我們將sessionId存儲在我們自己的上下文對象中,這是每個服務方法的第一個參數。每個服務方法都有一個攔截器,它從給定的上下文對象讀取sessionId並檢查會話是否仍然有效。客戶端需要首先調用登錄服務來獲取充滿sessionId的上下文對象,並在進一步的服務調用中重新使用該上下文對象。

public class OurContext { 
    private String sessionId; 
} 


@Stateless 
@Interceptors(SecurityInterceptor.class) 
public OurServiceImpl implements OurService { 

    public void doSomething(OurContext context, String param1) { 
     [...] 
    } 
} 

我不喜歡在這個解決方案的東西是污染每個服務方法與上下文參數。 在rmi調用中沒有類似http會話的機制嗎?我正在考慮將我們的上下文對象放入登錄後在客戶端(?)創建的某種會話中,並在每次服務調用時將其傳遞給服務器,以便SecurityInterceptor可以從此「魔術上下文」中讀取sessionId 」。

事情是這樣的:

OurContext ctx = service.login("user","password"); 
Magical(Jboss)Session.put("securContext", ctx); 
service.doSomething("just the string param"); 

回答

2

既然你已經使用的應用程序服務器,似乎你應該使用內置的EJB的安全機制,一般是通過JAAS提供。在4.x jboss行中,如果您爲jboss實現了自己的JAAS插件,則可以訪問通過遠程請求傳遞的「特殊」上下文映射(類似於您所描述的)(由jboss遠程調用框架)。我有一段時間沒有使用jboss,所以不知道它如何映射到5.1產品,但我必須想象它具有類似的設施。這當然假設你願意實現一些特定的jboss。

+0

好吧,在思考了很多關於你的答案後,我必須承認,我找不到更好的解決方案=)。所以我們會保持我們的背景情景是由政治原因引起的,hrmpf – martin 2012-01-12 09:07:35

1

EJB中有一些會話機制,但它們都在遠程調用開始時開始,並在結束時結束。舊的一個是交易背景(Adam Bien前段時間寫到這個),而CDI會議範圍則是一個更新的背景。與流行的觀點相反,該範圍不僅僅反映http會話範圍,而且在沒有HTTP會話(如遠程調用)的情況下,它表示單個調用鏈或消息傳遞(對於mdbs)。

有了這樣的會話,您的遠程SWT客戶端仍然必須將sessionId傳遞給遠程服務,但是從那裏調用的任何本地bean都可以從此「cdi」會話中獲取它。

其他選項有點像jtahlborn說的:用你自己的登錄模塊,你可以返回一個自定義主體,而不是默認的主體。你的代碼可以先請求正常的委託人,然後嘗試施放它。

問題是這個東西是特定於容器的,JBoss總是忘記它。它在每次更新之後都會中斷,用戶必須在下一個版本中進行修改才能修復它(僅在此版本中才能看到它再次中斷)。沒有JBoss真的支持這個,這是一場無盡的戰鬥。

還有一種選擇是讓用戶以sessionId作爲名稱登錄。後面的登錄模塊可以是一個簡單的模塊,它可以接受所有內容,只需將sessionId作爲「名稱」放入安全上下文中即可。這有點奇怪,但我們已經成功地使用它來獲取可以由字符串表示的任何數據到安全上下文中。當然,你需要讓你的客戶在這裏進行一次定期的容器認證,這首先會使用Spring安全性。

0

我們去了另一種便攜式的方法,它不依賴於特定的應用服務器。另外,我們的安全實現將我們從EJB方法的限制中解放出來(我認爲這種方法在二十年前就已經關閉了......但是再次出現)。

尋找自上而下:

沒有提供類與方法對同一數據工作的服務器。 客戶端提供數據並調用特定的方法。

我們的方法是將所有數據(因此客戶端和服務器之間的通信)放入「業務對象」中。每個BO都擴展一個超類。這個超類包含一個會話ID。登錄方法提供並返回該ID。每個客戶端只需確保將一個BO中收到的標識複製到下一個發送給服務器的標識中。可以遠程(或本地)調用的每種方法都首先使用收到的ID獲取會話對象。返回會話對象的方法還檢查安全約束(基於權限而不是基於EKB方法中的角色)。

+1

聽起來很不錯。對於沒有任何參數的服務方法,您的方法如何? – martin 2012-02-27 08:09:49