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>