2012-07-10 16 views
6

Tôi bị kẹt trong vấn đề này trong một thời gian dài. Tôi muốn sử dụng @Secure thêm Access Control để điều khiển của tôi ArticleController.java như thế này:Làm cách nào để <an toàn-phương pháp-bảo mật> hoạt động trên bộ điều khiển của tôi bằng 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 trả về một đối tượng JSON cho Articles nhưng chỉ quản lý có thể đọc chúng. OK bây giờ tôi cấu hình Spring-Security để thực hiện công việc này.

tôi sử dụng security setup chức năng của mùa xuân-ROO, các điều chỉnh cấu hình sau đây được tạo ra:

Trong 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> 

Trong 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> 

Trong /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> 

Trước tiên, tôi đã thử thêm <global-method-security mode="aspectj" secured-annotations="enabled" pre-post-annotations="enabled"/> vào /spring/applicationContext-security.xml nhưng không hoạt động. Sau đó, có lẽ bộ điều khiển không nằm trong bối cảnh tương tự của bối cảnh bảo mật, vì vậy tôi thêm số /spring/webmvc-config.xml bắt đầu bằng DispatcherServlet, không hoạt động.

Tôi cũng đã thêm một mặc định khác là applicationContext.xml, nó cũng không hoạt động. Tôi không biết làm thế nào để cấu hình các <global-method-security> mà có thể làm cho công việc bảo mật phương pháp. Có vẻ như tôi chỉ sử dụng một ngữ cảnh, tôi đã bỏ lỡ điều gì đó? Hy vọng thông tin là đủ để làm cho vấn đề này rõ ràng.

PS: Phương thức URL được tạo hoạt động rất tốt: <intercept-url pattern="/*.html" access="hasRole('ROLE_ADMIN')" />.

Added: Theo ý kiến ​​@LukeTaylor 's: Tôi thêm <global-method-security>-webmvc-config.xml và loại bỏ các mode="aspectj", nó hoạt động, và tôi đã làm một số thí nghiệm, vẫn có một số câu hỏi sau:

1) Nó hoạt động nhưng chỉ với ArticleController.java, thẻ @Secure trong ArticleController_Roo_Controller.aj vẫn không hoạt động, có phải cái gì đó liên quan đến "vẫy tay" không? 2) Bạn có thể giải thích cho tôi lý do tại sao mode=aspectj làm cho nó lộn xộn ở đây không?

+0

bản sao có thể có của [@ ​​Chú thích được bảo mật không hoạt động ở Chế độ AspectJ với Autoproxy] (http://stackoverflow.com/questions/11400503/secured-annotations-not-working-in-aspectj-mode-with-autoproxy) – axtavt

+0

Tại sao bạn không muốn sử dụng ''? Đó là cách làm tiêu chuẩn. – sourcedelica

+0

@sourcedelica bạn nói đúng, lý do tại sao tôi sử dụng roo là thuận tiện, tôi không thể dành nhiều thời gian hơn cho việc này. Nhưng các thẻ khác như '@ Async' cũng không thể hoạt động, vì vậy tôi nghĩ đến một số lỗi cấu hình có thể ai đó ở đây biết. – JerryCai

Trả lời

10

Theo đề xuất của @Luke Taylor trong các nhận xét, thẻ <sec:global-method-security/> cần được định nghĩa trong tệp dispatcher-servlet.xml (webmvc-config.xml trong trường hợp này). Và không cần phải có thuộc tính mode="aspectj".

Cảm ơn.

+2

Cảm ơn bạn SOOOOOO! Tôi đã đập đầu vào bức tường gạch đặc biệt này hàng giờ liền. Tại sao lại là mùa xuân? Tại sao bạn cần phải đặt cấu hình liên quan đến bảo mật trong cấu hình điều phối-serlvet của bạn và không phải trong cấu hình bảo mật của bạn ??? Tôi chắc chắn phải có một lý do chính đáng .... –

Các vấn đề liên quan