2013-03-29 70 views
4

我试图实现一个@Restricted注释,以便用户只有在登录并具有特定角色时才能访问它们的方式来保护控制器方法。我在使用JSF和CDI的Tomcat 7上,所以没有EJB。只要注解接口没有指定任何参数,拦截器就会被调用。只要我添加@Nonbinding Role value() default Role.ADMIN;参数,拦截器和控制器方法都不会执行。没有错误或例外。这里是我的代码,我真的不知道有什么地方错了:当注释有参数时,CDI拦截器不起作用

译注:

@InterceptorBinding 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ ElementType.TYPE, ElementType.METHOD }) 
public @interface Restricted { 
    @Nonbinding Role value() default Role.ADMIN; // ### 
} 

拦截:

@Interceptor 
@Restricted 
public class RoleBasedRestrictingInterceptor implements Serializable { 
    @Inject 
    ISecurityManager security; 

    @AroundInvoke 
    public Object intercept(final InvocationContext ctx) throws Exception { 
     final Restricted annotation = ctx.getClass().getAnnotation(Restricted.class); 
     log.info("Intercepted, required role is: {}", annotation.value()); // ### 
     log.info("User is logged in: {}", security.isLoggedIn()); 
     return ctx.proceed(); 
    } 
} 

控制器:

@Named("manageUsers") 
@SessionScoped 
public class ManageUsersBacking extends implements Serializable { 
    @Restricted(Role.ADMIN) // ### 
    public void testRestricted() { 
     log.info("testRestricted()"); 
    } 
} 

###事件标记需要更改或删除的内容以使其重新生效。拦截器在WEB-INF/beans.xml中正确定义,因为它在我的注释中没有role参数。

16:04:33.772 [http-apr-8080-exec-11] INFO c.m.s.RoleBasedRestrictingInterceptor - User is logged in: true 
16:04:33.772 [http-apr-8080-exec-11] INFO c.m.c.admin.ManageUsersBacking - testRestricted() 

回答

4

后一个漫长的故事[1] ...今天我重新审视这个特殊的问题,并发现它没有任何关系与CDI:

ctx.getClass().getAnnotation(Restricted.class)

显然,在我的例子中,没有一流水平的注解所以getAnnotation()返回null。相反,我应该使用以下内容:

ctx.getMethod().getAnnotation(Restricted.class)

虽然我不知道为什么那里没有任何例外。也许还有其他一些事情正在进行,我不能再复制,因为...

[1] ...我将我的申请迁移到TomEE,这是一个痛苦的屁股,花了我一个多星期。而且我仍然需要在生产环境中部署TomEE,并在Apache代理之后部署,因此仍需要完成一些配置。如果它终于出来了,可能值得付出努力,因为我也有一些其他的CDI问题(例如,注入到JAX-RS服务的CDI bean无法使用Weld + Resteasy + Tomcat),现在已经不存在了。我也喜欢EJB和容器管理的事务。但是,当有人试图将小部件甚至Java EE的一个子集与Tomcat一起使用时,我认为不鼓励赞美TomEE。它的许多API实现是,意思是可以在各种环境(甚至Java SE)中工作,这是一件好事。因此,如果您不需要TomEE来实现其某些高级Java EE功能,则不能推荐此举。一些问题将会消失,但其他问题将会出现。而且你不能再在不同的API实现中自由选择。但是,这不是针对TomEE的声明。习惯于Tomcat我真的很喜欢TomEE的想法。

0

这听起来像你有东西设置正确(beans.xml和拦截器)。你在使用哪种CDI实现?如果您使用Tomcat,您是否使用过TomEE?

+0

我正在使用焊接1.1.10.Final。我尝试用OpenWebBeans(这是TomEE使用的CDI实现)替换Weld,但OpenWebBeans项目网站上没有任何文档(请参阅http://openwebbeans.apache.org/documentation.html,每个链接都已中断)。看起来我需要一些OpenWebBeans Maven依赖来在Tomcat 7上使用它,但没有文档我不知道哪些依赖。如果我切换到TomEE,是不是需要相同的Maven依赖关系,但用'提供的'? – Jack

+0

是的,你会有提供的东西,而不是默认或编译。 – LightGuard

1

如果切换到TomEE你不需要依赖(Maven的)上实现,只是API(使用org.apache.openejb:JavaEE的-API:6.0-4与所提供的范围