2012-02-24 26 views
1

我目前有一些Web應用程序可以訪問在JBoss 5.0中運行的通用服務。該服務非常簡單,使用Guice和POJO。 Web應用程序經過身份驗證,並知道用戶是誰以及他們擁有什麼角色。在調用服務時,我應該如何將此身份驗證信息傳遞給服務?我應該如何在Java中的應用程序層之間傳遞主題/主體/角色?

看起來簡單的方法是簡單地向接口添加一個參數來獲取用戶信息。可能是一個主題。但是,這有一個不利的地方,就是手邊沒有特定的上下文信息。

void doSomething(Subject subject, ...) { 
} 

我所看到的另一種方法是使用ThreadLocal的存儲,調用前把用戶信息在那裏,並通過該服務可以使用一些工具類,這個訪問。這清除了界面,但隱藏了服務的客戶端在進行呼叫之前必須設置用戶信息的事實。

是否有另一種方法呢?我感覺AOP可能在這裏也有用,但看不出如何。我錯過了一些「最佳做法」嗎? EJB會提供幫助嗎?

+0

因爲我已經遇到[阿帕奇四郎(http://shiro.apache.org),它解決了這個問題。不知道如何,但它做到了。 – pauli 2012-05-14 09:16:45

回答

1

這清理了接口,但隱藏了這樣一個事實,即 服務的客戶端在撥打電話之前必須設置用戶信息。

確實如此,但是如果您需要將某些東西傳遞給整個應用程序中的特定方法,那麼您正在破壞使用依賴注入的目的。它就在那裏,因此您不必將一堆服務和對象傳遞給其他服務和對象等等,它們都是用他們需要的一切創建的。

是否有另一種方法呢?我感覺AOP可能也是 的使用在這裏,但不能完全看出如何。有沒有一些「最佳做法」 我錯過了? EJB會提供幫助嗎?

這樣做的另一種方法是在每個調用需要Subject/User的服務的Servlet上使用單個過濾器。將用戶設置在過濾器中,並在try-finally塊中最後清除用戶。實際上,OWASP Esapi在設置其ThreadLocalUser時使用此樣式,它允許用戶在應用程序的每個部分都可用。

事情是這樣的:

@Singleton 
public MyUserFilter extends FilterOfTheMonth { 

    private final Provider<Authenticator> authProvider; 

    @Inject 
    MyUserFilter(Provider<Authenticator> auth) { 
     this.authProvider = auth; 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, 
      FilterChain chain) throws java.io.IOException, ServletException { 
     try { 
      // Authenticate and SET the current user utilizing the request and/or      
      // session objects 
      authProvider.get().authenticateUser(HttpRequest currentRequest); 

      // Continue on here along the servlet chain 
      ... other processing 
     } finally { 
      authProvider.get().getRidOfCurrentUser(); 
     } 
    } 
} 
+0

你是對的,依賴注入是要走的路。我已經在整個網絡應用程序和服務中使用它 - 但這兩者完全分開,這就是爲什麼它不那麼直截了當地執行你的建議。我想我會像你建議的DI一樣提供auth提供程序,然後在impl中使用線程本地存儲來設置/訪問我的auth信息。無論如何,這將隱藏在服務中,因爲它只會使用DI'ed身份驗證提供程序。 – pauli 2012-02-28 16:29:14

+0

你是對的。 Owasp ESAPI目前正在嘗試製作一個利用DI的API。我只想確保AuthImpl中的其他所有內容都是線程安全的,並且在使用這些darn狀態單例時不要忘記擴展範圍注入的風險。祝你好運。 – oberger 2012-03-01 03:11:31

0

您是否考慮過將身份驗證過程轉移到通用服務?然後您只需要公共服務中的會話標識來標識請求來自的用戶的所有信息。

相關問題