Search code examples
gwtrequestfactoryfront-controller

FrontController with RequestFactory in GWT


I am using RequestFactory with GWT. It all working fine. I have a RequestContext interface that point to my DAO methodes.

Now I want to implement some kind of security check before calling the DAO. The first thing that comes to my mind is to use a FrontController and centralize the security in it, but I don't know to implement it with the RequestFactory. Any thought ?


Solution

  • Here's how I implemented the security checking:

    On the server side I check to see that every RequestFactory request is associated with a user who has previously logged in. To do this, the web.xml file (in the war/WEB-INF directory) must have a mapping for the servlet class. Here's the entry from the web.xml file:

    <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>
    

    The RFERequestFactoryServlet class contains the following code:

    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;
    }
    
    }
    

    On the client side I needed to intercept every RequestFactory response to check for the SC_UNAUTHORIZED error. You have to tell the RequestFactory object to use a specific RequestTransport in the RequestFactory#initialize invocation, like this:

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

    My RFERequestTransport class extends the DefaultRequestTransport class:

    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));
    }
    
    }
    

    When RequestFactory creates a request callback it calls my method, which creates my own version of a RequestCallback. If the user is logged in (as determined by the servlet) then it just performs the normal RequestFactory processing; otherwise, I go through the login process with the user. Part of the login process involves communication with the server to verify the login ... if the login is successful then I create an object on the server and store a reference to it in the "User" attribute - this is then checked in the userIsLoggedIn method in the servlet class.