2011-07-11 14 views
14

Parece que no se están leyendo los métodos @Secured on my @Controller. Cuando se usa el filtrado de seguridad basado en sec: intercept-url, parece que funciona correctamente. El código siguiente produce en la primavera de Seguridad darme esta entrada de registro:@Secured no funciona en el controlador, pero la URL de intercepción parece estar funcionando bien

DEBUG: - org.springframework.security.web.access.intercept.FilterSecurityInterceptor objeto público - autenticación no intentaron

web. xml

contextConfigLocation /WEB-INF/spring/root-context.xml

<!-- Creates the Spring Container shared by all Servlets and Filters --> 
<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

<!-- Processes application requests --> 
<servlet> 
    <servlet-name>appServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      /WEB-INF/spring/appServlet/servlet-context.xml 
     </param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

<!-- Filter security --> 
<filter> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>springSecurityFilterChain</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

servlet-context.xml contiene la configuración de los viewResolvers y toda la maniobra. Esta configuración es impulsada por anotaciones.

raíz context.xml

<sec:global-method-security secured-annotations="enabled" /> 

<sec:http auto-config="true"> 
    <sec:http-basic/> 
</sec:http> 

<!-- Declare an authentication-manager to use a custom userDetailsService --> 
<sec:authentication-manager> 
    <sec:authentication-provider 
     user-service-ref="userDetailsService"> 
     <sec:password-encoder ref="passwordEncoder" /> 
    </sec:authentication-provider> 
</sec:authentication-manager> 

<bean 
    class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder" 
    id="passwordEncoder" /> 
<sec:user-service id="userDetailsService"> 
    <sec:user name="john" password="john" authorities="ROLE_USER, ROLE_ADMIN" /> 
    <sec:user name="jane" password="jane" authorities="ROLE_USER" /> 
</sec:user-service> 

PingController.java

@Controller 
public class PingController { 

    @Secured("ROLE_ADMIN") 
    @RequestMapping(value = "/ping", method = RequestMethod.GET) 
    public void ping() { 
    } 

} 

Esto no parece tener ninguna relación con el método de autenticación que estoy usando, por lo que la basic-http-tag puede pasarse por alto.

Tengo la idea de que @Secured no funciona porque se usa en otro contexto distinto de root-context.xml en el que se está configurando la seguridad. Intenté mover esta configuración al servlet-context.xml, pero parece que no llega al springSecurityFilterChain. ¿Alguna idea sobre el problema y mi teoría?

Respuesta

23

Tiene razón, <global-method-security> se aplica por contexto. Sin embargo, no necesita mover toda la configuración de seguridad al servlet-context.xml, simplemente agregue un elemento <global-method-security>.

+0

Spot on. Muchas gracias, @axtavt! – kareblak

+0

¡Magnífico! Gracias :) – Athar

+1

Si está utilizando el modo de configuración de Java, puede agregar la anotación '@ EnableGlobalMethodSecurity' a su clase de configuración que amplía' WebMvcConfigurerAdapter'. – beat

9

Ver Spring Security FAQ (énfasis mío). Si aplica puntos a la capa de servicio, solo necesita establecer <global-method-security> en el contexto de seguridad de su aplicación.

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, recomiendo la aplicación de la seguridad en el método de la capa de servicio en lugar de en los controladores web individuales.

+0

Y así es como una aplicación web puede tener tantas interfaces como desee. Aplicarlo en la capa de servicio es la mejor opción, pero también hay una desventaja al hacer esto: en la mayoría de los casos, se aplicará un mapeo innecesario. – kboom

+0

¿Puedes refrescar la dirección del enlace? –

Cuestiones relacionadas