Весна безопасности: запретить доступ к контроллеру методы, если @авторизацию аннотации отсутствует

у меня есть веб-приложение, настроенное на использование Spring Security 3.2 стандартным способом.

я использую @PreAuthorize аннотация для защиты метода контроллеров. Теперь, я хотел бы запретить доступ к каждому методу контроллера если он аннотируется @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) {

        ...
    }

}

aop

используя выражение pointcut в глобальный метод бирка

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

этот подход также терпит неудачу: методы контроллеров, которые не аннотированы, по-прежнему доступны.

1 ответов


я отвечаю на свой вопрос.

Я решил проблему, используя HandlerInterceptorAdapter.

Я не уверен, что это самый весенний идиоматический способ достичь результата, но для меня этого достаточно.

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;
    }
}

и в весенней конфигурации:

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

<beans:bean id="mvcPreAuthorizeAnnotationCheckerInterceptor" class="com.acme.MvcPreAuthorizeAnnotationCheckerInterceptor"/>