Spring Security:如果缺少@PreAuthorize注释,则拒绝访问控制器方法

Luc*_*sio 7 java spring spring-security

我有一个Web应用程序配置为以标准方式使用Spring Security 3.2.

我正在使用@PreAuthorize注释来保护Controllers方法.现在,我想拒绝访问每个控制器方法,除非它被注释@PreAuthorize.

我尝试了以下方法:

超级控制器

每个控制器都从一个带有注释的超级控制器扩展:@PreAutorize("denyAll").这种方法似乎不起作用,因为忽略了控制器的方法注释.一切都是被禁止的.

@PreAutorize("denyAll") 
public class SuperController {

}

public class MyController extends SuperController {

    @PreAuthorize("hasRole('SUPERHERO')")
    @RequestMapping(value = URL_PREFIX + "Add.do", method =  RequestMethod.GET)
    public String doStuff(Model model) {

        ...
    }

}
Run Code Online (Sandbox Code Playgroud)

AOP

在全局方法安全标记中使用切入点表达式

<global-method-security pre-post-annotations="enabled">
    <protect-pointcut expression="execution(* com.acme.*Controller.*(..))" access="denyAll" />
 </global-method-security>
Run Code Online (Sandbox Code Playgroud)

这种方法也失败了:仍然可以访问未注释的控制器方法.

Luc*_*sio 4

我在这里回答我自己的问题。

我通过使用HandlerInterceptorAdapter解决了这个问题。

我不确定这是实现结果的最 Spring 惯用的方法,但它对我来说已经足够好了。

public class MvcPreAuthorizeAnnotationCheckerInterceptor extends HandlerInterceptorAdapter {
    final HandlerMethod hm;
    if (handler instanceof HandlerMethod) {
        hm = (HandlerMethod) handler;
        PreAuthorize annotation = hm.getMethodAnnotation(PreAuthorize.class);
        if (annotation == null) {
            // check if the class is annotated...
            annotation = hm.getMethod().getDeclaringClass().getAnnotation(PreAuthorize.class);
            if (annotation == null) {
                // add logging
                // or send a NON AUTHORIZED
                response.sendRedirect(request.getContextPath());
            }
       }
       return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

在 Spring 配置中:

<mvc:interceptors>
    <beans:ref bean="mvcPreAuthorizeAnnotationCheckerInterceptor"/>
</mvc:interceptors>

<beans:bean id="mvcPreAuthorizeAnnotationCheckerInterceptor" class="com.acme.MvcPreAuthorizeAnnotationCheckerInterceptor"/>
Run Code Online (Sandbox Code Playgroud)