2010-06-21 14 views

Respuesta

63

Sí, funciona bien.

Necesita <security:global-method-security pre-post-annotations="enabled" /> en ...-servlet.xml. También requiere CGLIB proxies, por lo tanto, sus controladores no deberían tener interfaces, o debe usar proxy-target-class = true.

+1

que poner eso en mi contexto de aplicación de seguridad de muelle (que ya tenía en realidad), pero Spring no hace nada con los controladores que usan @Controller. ¿Tengo que hacer algo especial para que esto funcione más allá de lo que dices? En – egervari

+13

dije, 'global-method-security' debería estar en el contexto de DispatcherServlet (' ...- servlet.xml') no en "contexto de la aplicación de seguridad de primavera". – axtavt

+0

Gracias! No lo moví porque no podía ver por qué iba a hacer una diferencia, ya que se fusiona ... Supongo que no lo hizo;) ¡Funciona ahora! – egervari

20

Ver Spring Security FAQ (énfasis mío).

En una aplicación web de Primavera, el contexto de aplicación que contiene los granos de Spring MVC para el servlet despachador es a menudo separado del contexto de aplicación principal . A menudo se define en un archivo llamado myapp-servlet.xml, donde "myapp" es el nombre asignado al Spring DispatcherServlet en web.xml. Una aplicación puede tener múltiples DispatcherServlets, cada uno con su propio contexto de aplicación aislado. Los beans en estos contextos "secundarios" no son visibles para el resto de la aplicación . El contexto de la aplicación "principal" se carga con el ContextLoaderListener que define en su web.xml y está visible para todos los contextos secundarios . Este contexto primario generalmente es donde define su configuración de seguridad, incluido el elemento ). Como resultado, las limitaciones de seguridad aplicadas a los métodos en estos beans web no se aplicarán, ya que los beans no se pueden ver desde el contexto DispatcherServlet. Debe mover la declaración al contexto web o mover los beans que desea asegurar en el contexto de la aplicación principal.

En general, recomendaríamos aplicar la seguridad del método en la capa de servicio en lugar de en los controladores web individuales.

Si se aplica a la capa pointcuts servicio solo es necesario para establecer <global-method-security> en el contexto de seguridad de la aplicación.

+0

Estaba tratando de usar @PreAuthorize en el controlador, no funcionó, funcionó una vez que me mudé a la capa de servicio. – MarCrazyness

16

Si está utilizando Spring 3.1, puede hacer algunas cosas muy interesantes con esto. Eche un vistazo al https://github.com/mohchi/spring-security-request-mapping. Es un proyecto de ejemplo que se integra con @PreAuthorize RequestMappingHandlerMapping de Spring MVC para que pueda hacer algo como:

@RequestMapping("/") 
@PreAuthorize("isAuthenticated()") 
public String authenticatedHomePage() { 
    return "authenticatedHomePage"; 
} 

@RequestMapping("/") 
public String homePage() { 
    return "homePage"; 
} 

Una petición de "/" va a llamar authenticatedHomePage() si el usuario es autenticado. De lo contrario, llamará homePage().

9

Hace más de dos años que se formuló esta pregunta, pero debido a problemas que tuve hoy, preferiría desalentar el uso de @Secured, @PreAuthorize, etc. en @Controller s.

Lo que no funcionó para mí fue @Validated combinarse con @Secured controlador:

@Controller 
@Secured("ROLE_ADMIN") 
public class AdministrationController { 

// @InitBinder here... 

@RequestMapping(value = "/administration/add-product", method = RequestMethod.POST) 
public String addProductPost(@ModelAttribute("product") @Validated ProductDto product, BindingResult bindingResult) { 
    // ... 
} 

Validador simplemente no lo hace el fuego (Spring MVC 4.1.2, 3.2.5 Seguridad de Primavera) y se llevan a cabo ninguna comprobación.

problemas similares son causados ​​por los proxies CGLIB utilizados para la primavera (cuando no hay interfaz implementada por una clase, Primavera crea CGLIB de proxy, si la clase implementa cualquier interfaz entonces se genera JDK proxy - documentation, well explained here y here).

Como se menciona en las respuestas que he vinculado anteriormente, es mejor utilizar las anotaciones de Spring Security en la capa de servicio que generalmente implementa interfaces (por lo que se utilizan los Proxy JDK) ya que esto no genera tales problemas.

Si desea proteger los controladores web, la mejor idea es usar <http> y <intercept-url /> que están vinculados a direcciones URL específicas en lugar de métodos en controladores y funcionan bastante bien. En mi caso:

<http use-expressions="true" disable-url-rewriting="true"> 

    ... 

    <intercept-url pattern="/administration/**" access="hasRole('ROLE_ADMIN')" /> 

</http> 
1

para extender la respuesta proporcionada por Andy, puede utilizar:

@PreAuthorize("hasRole('foo')") 

para comprobar la función específica.

2

Ya existe una respuesta sobre cómo hacer que funcione cambiando la configuración xml; Sin embargo, si se está trabajando con la configuración basada en el código, puede lograr el mismo mediante la colocación de la siguiente anotación sobre su clase @Configuration:

@EnableGlobalMethodSecurity(prePostEnabled=true) 
Cuestiones relacionadas