GWT + Seam WebRemote with Seam security problem
ktcorby Jun 13, 2008 3:31 PMI am working on an application that uses Session beans on the server side that are exposed to a GWT client using the Seam WebRemote annotation. I started adding in security based on the Seam @Restrict annotation to limit access to the session beans to users that are logged in. This is working fairly well, but I've hit a hitch with exception handling.
When the user isn't logged in the methods with a @Restrict annotation send a NotLoggedInException which is derived from RuntimeException. RuntimeExceptions all get translated to a generic InvocationException in GWT. In the client I need to be able to differentiate a NotLoggedInException from other exceptions.
I tried to address this by adding an interceptor to translate the NotLoggedInException to a different checked exception. However, this is not working because I can't seem to get my interceptor to run outside of Seam's security interceptor. I've tried lots of different setups but nothing seems to work.
Here is my current code:
package com.ccri.gotm.auth; import com.ccri.gotm.auth.exceptions.NotLoggedInException; import org.jboss.seam.annotations.intercept.AroundInvoke; import org.jboss.seam.annotations.intercept.Interceptor; import org.jboss.seam.annotations.intercept.InterceptorType; import org.jboss.seam.intercept.InvocationContext; import org.jboss.seam.security.SecurityInterceptor; @Interceptor(stateless=true,type=InterceptorType.CLIENT,around=SecurityInterceptor.class) public class TranslateExceptionsForClientInterceptor /* extends AbstractInterceptor */ { @AroundInvoke public Object aroundInvoke(InvocationContext invocation) throws Exception { try { Object o = invocation.proceed(); return o; } catch (org.jboss.seam.security.NotLoggedInException notLoggedInException) { throw new NotLoggedInException(); } } }
package com.ccri.gotm.auth; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import org.jboss.seam.annotations.intercept.Interceptors; @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Interceptors(TranslateExceptionsForClientInterceptor.class) @Inherited public @interface TranslateExceptionsForClient { }
package com.ccri.gotm.analysis.dao; import com.ccri.gotm.analysis.entity.Analysis; import com.ccri.gotm.auth.TranslateExceptionsForClient; import com.ccri.gotm.dao.GenericDAOImpl; import javax.ejb.Stateless; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.security.Restrict; @Stateless @Name("com.ccri.gotm.gwt.client.analysis.endpoint.AnalysisDAOEndpoint") @TranslateExceptionsForClient public class AnalysisDAOBean extends GenericDAOImpl<Analysis, Long> implements AnalysisDAOLocal { public AnalysisDAOBean() { super(Analysis.class); } @Override @Restrict("#{identity.loggedIn}") public void save(Analysis analysis) { super.save(analysis); } }
package com.ccri.gotm.analysis.dao; import com.ccri.gotm.analysis.entity.Analysis; import com.ccri.gotm.dao.GenericDAO; import java.util.List; import javax.ejb.Local; import org.jboss.seam.annotations.remoting.WebRemote; @Local public interface AnalysisDAOLocal extends GenericDAO<Analysis, Long> { @Override @WebRemote List<Analysis> list(); @Override @WebRemote void save(Analysis analysis); }
<?xml version="1.0" encoding="UTF-8"?> <ejb-jar version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd"> <interceptors> <interceptor> <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class> </interceptor> </interceptors> <assembly-descriptor> <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>org.jboss.seam.ejb.SeamInterceptor</interceptor-class> </interceptor-binding> </assembly-descriptor> </ejb-jar>