2013-03-26 43 views
0

我在GWT中使用RequestFactory。這一切工作正常。我有一個指向我的DAO方法的RequestContext接口。GWT中帶有RequestFactory的FrontController

現在我想在調用DAO之前執行某種安全檢查。我想到的第一件事是使用FrontController並集中安全性,但我不知道如何使用RequestFactory實現它。任何想法 ?

+0

你想做什麼樣的安全檢查?測試用戶身份驗證? – Sam 2013-03-26 15:38:28

+0

基本上我想檢查用戶是否有活動會話。 – outellou 2013-03-26 15:41:02

回答

1

下面是如何實施的安全檢查:

在服務器端我檢查,看看每一個RequestFactory請求與誰在先前已登錄用戶相關聯。爲了做到這一點,web.xml文件(在war/WEB-INF目錄中)必須具有servlet類的映射。下面是來自web.xml文件中的條目:

<servlet> 
    <servlet-name>requestFactoryServlet</servlet-name> 
    <servlet-class>org.greatlogic.rfexample2.server.RFERequestFactoryServlet</servlet-class> 
    <init-param> 
    <param-name>symbolMapsDirectory</param-name> 
    <param-value>WEB-INF/classes/symbolMaps/</param-value> 
    </init-param> 
</servlet> 
<servlet-mapping> 
    <servlet-name>requestFactoryServlet</servlet-name> 
    <url-pattern>/gwtRequest</url-pattern> 
</servlet-mapping> 

RFERequestFactoryServlet類包含以下代碼:

public class RFERequestFactoryServlet extends RequestFactoryServlet { 

@Override 
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) 
    throws IOException, ServletException { 
    if (!userIsLoggedIn(request)) { 
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
    } 
    else { 
    super.doPost(request, response); 
    } 
} 

private boolean userIsLoggedIn(final HttpServletRequest request) { 
    boolean result = false; 
    HttpSession session = request.getSession(); 
    if (session != null) { 
    User user = (User)session.getAttribute("User"); 
    result = user != null; 
    } 
    return result; 
} 

} 

在客戶端我需要截獲每個RequestFactory反應來檢查SC_UNAUTHORIZED錯誤。你必須告訴RequestFactory對象使用特定RequestTransportRequestFactory#initialize調用,就像這樣:

MyRequestFactory requestFactory = GWT.create(MyRequestFactory.class); 
requestFactory.initialize(eventBus, new RFERequestTransport()); 

RFERequestTransport類擴展DefaultRequestTransport類:

public class RFERequestTransport extends DefaultRequestTransport { 

private final class RFERequestCallback implements RequestCallback { 

private RequestCallback _requestCallback; 

private RFERequestCallback(final RequestCallback requestCallback) { 
    _requestCallback = requestCallback; 
} 

@Override 
public void onError(final Request request, final Throwable exception) { 
    _requestCallback.onError(request, exception); 
} 

@Override 
public void onResponseReceived(final Request request, final Response response) { 
    if (response.getStatusCode() == Response.SC_UNAUTHORIZED) { 
    // the login processing goes here 
    } 
    else { 
    _requestCallback.onResponseReceived(request, response); 
    } 
} 

} // end of the RFERequestCallback class 

@Override 
protected RequestCallback createRequestCallback(final TransportReceiver receiver) { 
    return new RFERequestCallback(super.createRequestCallback(receiver)); 
} 

} 

RequestFactory創建它調用的請求回調我的方法,它創建了我自己的版本RequestCallback。如果用戶登錄(由servlet確定),那麼它只執行正常的RequestFactory處理;否則,我會與用戶一起完成登錄過程。部分登錄過程涉及與服務器通信以驗證登錄...如果登錄成功,則我在服務器上創建一個對象並在「用戶」屬性中存儲對其的引用 - 然後在userIsLoggedIn中進行檢查方法在servlet類中。

+0

如何管理第一個登錄請求?因爲會話尚未創建 – outellou 2013-04-02 16:11:43

+0

@Moh在'RFERequestFactoryServlet#userIsLoggedIn'我正在執行'HttpServletRequest#getSession'。此方法的JavaDoc狀態爲:返回與此請求關聯的當前會話,或者如果請求沒有會話,則創建一個會話。 – 2013-04-02 22:16:57

+0

我瞭解'HttpSession'部分。但是,當用戶從會話中獲取時,它可能爲空,如果沒有用戶登錄,這將是正常的。現在我的問題是,當我調用登錄的DAO中的方法時,該呼叫將被處理'RFERequestFactoryServlet#userIsLoggedIn',並且因爲會話中沒有用戶,所以登錄請求不會經過並且將顯示登錄視圖。如何讓登錄請求通過,即使沒有用戶在會話中? – outellou 2013-04-03 17:42:26

3

如果要測試用戶是否已通過身份驗證,則可以在服務器端使用servlet篩選器,並在客戶端使用自定義RequestTransport。例如,請參閱guice-rf-activity原型https://github.com/tbroyer/gwt-maven-archetypes

您也可以通過使用自定義ServiceLayerDecorator貫徹invoke方法,調用report()當用戶未授權/認證(和處理在客戶端的onFailure)檢查方法級別。我實現了這樣的事情,即授權用戶基於服務方法或類上的@RolesAllowed註釋:https://gist.github.com/tbroyer/6091533

1

在您的web.xml中設置過濾器,以便每個RF請求都被過濾以驗證會話。

<filter> 
    <filter-name>AuthFilter</filter-name> 
    <filter-class>my.namespace.AuthFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>AuthFilter</filter-name> 
    <url-pattern>/gwtRequest</url-pattern> 
</filter-mapping> 

這裏有一個例子類,檢查是否有一定參數是可能在登錄過程中設置爲你的應用程序會話,這只是一個例子,你可以使用自己的機制。

public class AuthFilter implements Filter { 

    public void doFilter(ServletRequest servletRequest, 
     ServletResponse servletResponse, FilterChain filterChain) 
     throws IOException, ServletException { 

     HttpServletRequest req = (HttpServletRequest) servletRequest; 
     HttpServletResponse resp = (HttpServletResponse) servletResponse; 

     if (req.getSession().getAttribute("VALID_SESSION") == null) { 
     resp.sendError(HttpServletResponse.SC_UNAUTHORIZED); 
     return; 
     } 

     if (null != filterChain) { 
     filterChain.doFilter(req, resp); 
     } 

    } 
    }