views:

65

answers:

1
+2  Q: 

GWT Authentication

Hi, I'm developing a GWT+Spring application and I'm having hard times integrating GWT with Spring Security system.

Services are protected by spring security and response with 401 for un-authenticated users (anonymous) and 403 for unauthorized access. My problem here is that I can not make failed AsyncRequests handle those errors the way I want without typing again and again onFailure boilerplate stubs for that handling.

I've managed to develop my own filter for Spring Security that respondes with "authorizeform" header that carries URL of login form for 401 exception.

So the question is: Is there any way to handle 401/403 exceptions globaly without boilerplate onFailure code and redirect to URL from specified header?

Upcoming RequestFactory has something like "AuthenticationFailedHandler" but 2.1 is almost completely undocumented yet and "under rapid developement" so it looks like it's not an option.

Thanks in advance!

A: 

A very simple way to handle the security failures at the application level is to define an abstract callback for your application which will take care of the onFailure boilerplate in one consistent place. For each service request throughout your code, you will be able to use the callback and implement any specific handling.

public abstract class ServiceCallback<T> implements MethodCallback<T> {
private ServiceCallbackListener listener;

public ServiceCallback(ServiceCallbackListener serviceCallbackActions) {
    this.listener = serviceCallbackActions;
}

@Override
public void onFailure(Method method, Throwable exception) { 
    if (method.getResponse().getStatusCode() == 403 || method.getResponse().getStatusCode() == 401) {
        listener.onUnAuthorizedAccess();
    } else {
        onError(method, exception);
    }
}

public abstract void onError(Method method, Throwable exception);
}

You can now call a service in the following manner:

service.callToServer(new ServiceCallback<ServiceResponse>(sessionListener) {
        @Override
        public void onSuccess(Method method, ServiceResponse response) {
            Log.debug("It worked!");
        }

        @Override
        public void onError(Method method, Throwable exception) {
            Log.debug("Didn't work.. ");
        }
    });

Of course, if you would like the error handling to be only at the application level, you may want to set onError to be a non abstract method with an empty body.

RaphaelO