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