2012-07-10 9 views
6

Estoy atrapado en este problema por un largo tiempo. Quiero usar @Secure añadir control de acceso al controlador de ArticleController.java así:¿Cómo funciona <global-method-security> en mi controlador por Spring-Security?

@RequestMapping(headers = "Accept=application/json") 
@ResponseBody 
@Secured("ROLE_ADMIN") 
public ResponseEntity<String> listJson() { 
    HttpHeaders headers = new HttpHeaders(); 
    headers.add("Content-Type", "application/json; charset=utf-8"); 
    List<Article> result = Article.findAllArticles(); 
    return new ResponseEntity<String>(Article.toJsonArray(result), headers, HttpStatus.OK); 
} 

listJson devolver un objeto JSON para Articles pero sólo el administrador puede leerlos. Bien, ahora configuro Spring-Security para que esto funcione.

utilizo security setup función de Primavera-ROO, los siguientes configura de creación:

En web.xml:

 <context-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value> 
    </context-param> 
.... 
    <servlet> 
     <servlet-name>BabyPortal</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <init-param> 
      <param-name>contextConfigLocation</param-name> 
      <param-value>WEB-INF/spring/webmvc-config.xml</param-value> 
     </init-param> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

En spring/webmvc-config.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:security="http://www.springframework.org/schema/security" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd     http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd"> 

    <tx:annotation-driven/> 
    <!-- The controllers are autodetected POJOs labeled with the @Controller 
     annotation. --> 
    <context:component-scan base-package="com.tongxinyuan.babyportal" 
     use-default-filters="false"> 
     <context:include-filter expression="org.springframework.stereotype.Controller" 
      type="annotation" /> 
    </context:component-scan> 

    <!-- Turns on support for mapping requests to Spring MVC @Controller methods 
     Also registers default Formatters and Validators for use across all @Controllers --> 
    <mvc:annotation-driven conversion-service="applicationConversionService" /> 


    <!-- Handles HTTP GET requests for /resources/** by efficiently serving 
     up static resources --> 
    <mvc:resources location="/, classpath:/META-INF/web-resources/" 
     mapping="/resources/**" /> 

    <!-- Allows for mapping the DispatcherServlet to "/" by forwarding static 
     resource requests to the container's default Servlet --> 
    <mvc:default-servlet-handler /> 

    <!-- Register "global" interceptor beans to apply to all registered HandlerMappings --> 
    <mvc:interceptors> 
     <bean class="org.springframework.web.servlet.theme.ThemeChangeInterceptor" /> 
     <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor" 
      p:paramName="lang" /> 
    </mvc:interceptors> 

    <!-- Selects a static view for rendering without the need for an explicit 
     controller --> 
    <mvc:view-controller path="/login" /> 
    <mvc:view-controller path="/" view-name="index" /> 
    <mvc:view-controller path="/uncaughtException" /> 
    <mvc:view-controller path="/resourceNotFound" /> 
    <mvc:view-controller path="/dataAccessFailure" /> 

    <!-- Resolves localized messages*.properties and application.properties 
     files in the application to allow for internationalization. The messages*.properties 
     files translate Roo generated messages which are part of the admin interface, 
     the application.properties resource bundle localizes all application specific 
     messages such as entity names and menu items. --> 
    <bean 
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource" 
     id="messageSource" p:basenames="WEB-INF/i18n/messages,WEB-INF/i18n/application" 
     p:fallbackToSystemLocale="false" /> 

    <!-- Store preferred language configuration in a cookie --> 
    <bean class="org.springframework.web.servlet.i18n.CookieLocaleResolver" 
     id="localeResolver" p:cookieName="locale" /> 

    <!-- Resolves localized <theme_name>.properties files in the classpath to 
     allow for theme support --> 
    <bean 
     class="org.springframework.ui.context.support.ResourceBundleThemeSource" 
     id="themeSource" /> 

    <!-- Store preferred theme configuration in a cookie --> 
    <bean class="org.springframework.web.servlet.theme.CookieThemeResolver" 
     id="themeResolver" p:cookieName="theme" p:defaultThemeName="standard" /> 

    <!-- This bean resolves specific types of exceptions to corresponding logical 
     - view names for error views. The default behaviour of DispatcherServlet 
     - is to propagate all exceptions to the servlet container: this will happen 
     - here with all other types of exceptions. --> 
    <bean 
     class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" 
     p:defaultErrorView="uncaughtException"> 
     <property name="exceptionMappings"> 
      <props> 
       <prop key=".DataAccessException">dataAccessFailure</prop> 
       <prop key=".NoSuchRequestHandlingMethodException">resourceNotFound</prop> 
       <prop key=".TypeMismatchException">resourceNotFound</prop> 
       <prop key=".MissingServletRequestParameterException">resourceNotFound</prop> 
      </props> 
     </property> 
    </bean> 

    <!-- Enable this for integration of file upload functionality --> 
    <bean 
     class="org.springframework.web.multipart.commons.CommonsMultipartResolver" 
     id="multipartResolver" /> 
    <bean 
     class="com.tongxinyuan.babyportal.controller.ApplicationConversionServiceFactoryBean" 
     id="applicationConversionService" /> 
    <bean class="org.springframework.web.servlet.view.UrlBasedViewResolver" 
     id="tilesViewResolver"> 
     <property name="viewClass" 
      value="org.springframework.web.servlet.view.tiles2.TilesView" /> 
    </bean> 
    <bean class="org.springframework.web.servlet.view.tiles2.TilesConfigurer" 
     id="tilesConfigurer"> 
     <property name="definitions"> 
      <list> 
       <value>/WEB-INF/layouts/layouts.xml</value> 
       <!-- Scan views directory for Tiles configurations --> 
       <value>/WEB-INF/views/**/views.xml</value> 
      </list> 
     </property> 
    </bean> 

    <security:global-method-security mode="aspectj" secured-annotations="enabled" pre-post-annotations="enabled"/> 

</beans> 

En /spring/applicationContext-security.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans:beans xmlns="http://www.springframework.org/schema/security" 
    xmlns:beans="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> 
    <!-- HTTP security configurations --> 
    <http auto-config="true" use-expressions="true"> 
     <form-login login-processing-url="/resources/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t" /> 
     <logout logout-url="/resources/j_spring_security_logout" /> 
     <!-- Configure these elements to secure URIs in your application --> 
     <intercept-url pattern="/choices/**" access="hasRole('ROLE_ADMIN')" /> 
     <intercept-url pattern="/member/**" access="isAuthenticated()" /> 
     <intercept-url pattern="/resources/**" access="permitAll" /> 
     <intercept-url pattern="/*.html" access="hasRole('ROLE_ADMIN')" /> 
    </http> 
    <!-- Configure Authentication mechanism --> 
    <authentication-manager alias="authenticationManager"> 
     <authentication-provider> 
      <user-service> 
       <user name="admin" password="admin" authorities="ROLE_ADMIN" /> 
       <user name="user" password="user" authorities="ROLE_USER" /> 
      </user-service> 
     </authentication-provider> 
    </authentication-manager> 
</beans:beans> 

Primero traté de agregar el <global-method-security mode="aspectj" secured-annotations="enabled" pre-post-annotations="enabled"/> al /spring/applicationContext-security.xml pero no funcionó. Entonces tal vez el controlador no está en el mismo contexto de contexto de seguridad, por lo que agrego el a /spring/webmvc-config.xml que comenzó con DispatcherServlet, no funcionó.

También agregué otro predeterminado applicationContext.xml, tampoco funcionó. No sé cómo configurar el <global-method-security> que puede hacer que la seguridad del método funcione. Parece que solo uso un contexto, ¿extrañé algo? Espero que la información sea suficiente para aclarar este tema.

PD: El método de URL generado funciona muy bien: <intercept-url pattern="/*.html" access="hasRole('ROLE_ADMIN')" />.

Agregado: De acuerdo con los comentarios @LukeTaylor 's: He añadido el <global-method-security>-webmvc-config.xml y se retira el mode="aspectj", funciona, y yo algunos experimentos, todavía tiene algunas preguntas:

1) Funciona pero solo para ArticleController.java, la etiqueta @Secure en ArticleController_Roo_Controller.aj aún no funciona, ¿es algo relacionado con "agitar"? 2) ¿Puede explicarme por qué mode=aspectj lo hace desordenar aquí?

+0

posible duplicado de [@ Anotaciones seguras que no funcionan en el modo AspectJ con Autoproxy] (http://stackoverflow.com/questions/11400503/secured-annotations-not-working-in-aspectj-mode-with-autoproxy) – axtavt

+0

¿Por qué no quieres usar ''? Esa es la forma estándar de hacer esto. – sourcedelica

+0

@sourcedelica tienes razón, la razón por la que uso roo es por su conveniencia, no puedo pasar más tiempo en esto. Pero otras etiquetas como '@ Async' tampoco pueden funcionar, así que estoy pensando en algún error de configuración que alguien aquí sepa. – JerryCai

Respuesta

10

Según lo sugerido por @Luke Taylor en los comentarios, la etiqueta <sec:global-method-security/> debe definirse en el archivo dispatcher-servlet.xml (webmvc-config.xml en este caso). Y no es necesario tener el atributo mode="aspectj".

Gracias.

+2

¡Gracias SOOOOOO! He estado golpeando mi cabeza contra esta pared de ladrillo en particular durante horas. ¿Por qué Spring? ¿Por qué necesita poner configuración relacionada con la seguridad en su configuración dispatcher-serlvet y no en su configuración de seguridad? Estoy seguro de que debe haber una buena razón ... –

Cuestiones relacionadas