2015-05-20 5 views
5

Ho un'applicazione Web configurata per utilizzare Spring Security 3.2 in modo standard.Spring Security: nega l'accesso ai metodi del controller, se manca l'annotazione @PreAuthorize

Sto utilizzando l'annotazione @PreAuthorize per proteggere il metodo Controllers. Ora, vorrei negare l'accesso a ciascun metodo di controller UNLESS è annotato con @PreAuthorize.

Ho provato i seguenti approcci:

super-regolatore

Ogni controller si estende da un controllore super-annotato con: @PreAutorize("denyAll"). Questo approccio non sembra funzionare perché le annotazioni dei metodi dei controllori sono ignorate. Tutto è proibito

@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

Usando un'espressione pointcut nel tag globale metodo di protezione

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

Questo approccio fallisce anche: i metodi di controllori che non sono annotati sono ancora accessibili.

risposta

1

Sto rispondendo alla mia domanda qui.

Ho risolto il problema utilizzando un HandlerInterceptorAdapter.

Non sono sicuro che sia il modo più idiomatico di Spring per ottenere il risultato, ma è abbastanza buono per me.

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

E nella configurazione primavera:

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

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