How to handle session expired exception in Spring MVC-Spring Security app for GWT RPC calls

僤鯓⒐⒋嵵緔 提交于 2019-12-04 11:50:19

I suppose that for processing of incoming GWT call you use some Spring MVC controller or some servlet. It can have following logic

try{
    // decode payload from  GWT call
    com.google.gwt.user.server.rpc.RPC.decodeRequest(...)
    // get spring bean responsible for actual business logic
    Object bean = applicationContext.getBean(beanName);
    // execute business logic and encode response
    return RPC.invokeAndEncodeResponse(bean, ….)
} catch (com.google.gwt.user.server.rpc.UnexpectedException ex) {
    // send unexpected exception to client
    return RPC.encodeResponseForFailure(..., new MyCustomUnexpectedException(), …) ;
}

Solution for this case

HttpServletRequest request = getRequest() ; 
if (request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid()) {
    return RPC.encodeResponseForFailure(..., new MyCustomSessionExpiredException(), …) ;
} else {
    // first code snippet goes here
}

Then catch custom session expired exception in a client side code. If you do not use RPC directly then provide more details about your bridge implementation between GWT and Spring.

You will need also force GWT compiler to include MyCustomSessionExpiredException type to a serialization white list (to prevent case when GWT security policy stops propogation of the exception to client side). Solution: include MyCustomSessionExpiredException type to each method signature of each synchronous interface:

@RemoteServiceRelativePath("productRpcService.rpc")
public interface ProductRpcService extends RemoteService {
    List<Product> getAllProducts() throws ApplicationException;
    void removeProduct(Product product) throws ApplicationException;
}

MyCustomSessionExpiredException extends ApplicationException

Then show pop-up in client side code:

public class ApplicationUncaughtExceptionHandler implements GWT.UncaughtExceptionHandler {
    @Override        
    public void onUncaughtException(Throwable caught) {
        if (caught instanceof MyCustomSessionExpiredException) {
            Window.alert("Session expired");
        }
    }
}

// Inside of EntryPoint.onModuleLoad method
GWT.setUncaughtExceptionHandler(new ApplicationUncaughtExceptionHandler());

I researched a bit and uploaded the solution here http://code.google.com/p/gspring/source/browse/#svn%2Ftrunk%2Fsample%2Fsession-expired%253Fstate%253Dclosed.

Use mvn jetty:run-war to see the demo after checking it out and go to rpc-security-sample/index.htm

There are two ways to solve it.

The first is around to pass the delegate proxy for GWT RemoteServlet which throws SessionExpiredException during method invocation. This requires to declare Exception in every RPC service method. Example: http://code.google.com/p/gspring/source/browse/#svn%2Ftrunk%2Fsample%2Fsession-expired%253Fstate%253Dclosed

Steps:

  1. Develop new filter which intercepts first

  2. Declare SessionExpiredException in each RPC method service which could inherit RuntimeException for simplicity (no need to follow this in implementers)

  3. Develop parent generic AsyncCallback handler

  4. Use http://code.google.com/p/gspring/ solution to handle all incoming RCP requests.

The second which is much more simplest: return the 401 HTTP error and handle in UI side (GWT native general exception contains the HTTP status number). Example: http://code.google.com/p/gspring/source/browse/#svn%2Ftrunk%2Fsample%2Fsession-expired-401

The second approach is simplest and does not require declaring Exception in service methods contract. However following the first approach can give you some flexibility: it could contain some additional info like last login time (for SessionExpiredException) etc. Also the second approach can introduce new exceptions which are inherited from SecurityException like blacklisted user (for example if user was blacklisted during his session) or for example if user does the same actions very often like a robot (it could be asked for passing the captcha) etc.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!