Spring-Security如何在我的控制器上运行<global-method-security>?</global-method-security>

时间:2012-07-10 13:51:57

标签: spring-mvc spring-security spring-roo

我长期坚持这个问题。我想使用@Secure向我的控制器ArticleController.java添加访问控制,如下所示:

@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返回Articles的Json对象,但只有Admin可以读取它们。好的,现在我配置Spring-Security来实现这个功能。

我使用Spring-ROO的security setup函数,生成以下配置:

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

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>

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

首先,我尝试将<global-method-security mode="aspectj" secured-annotations="enabled" pre-post-annotations="enabled"/>添加到/spring/applicationContext-security.xml但不起作用。那么也许控制器不在安全上下文的相同上下文中,所以我添加了以DispatcherServlet开头的/spring/webmvc-config.xml,但是没有用。

我还添加了另一个默认applicationContext.xml,它也没有用。我不知道如何配置可以使方法安全性工作的<global-method-security>。我似乎只使用一个上下文,我错过了什么吗?希望这些信息足以使这个问题变得清晰。

PS:生成的网址方法非常有效:<intercept-url pattern="/*.html" access="hasRole('ROLE_ADMIN')" />

加了: 根据@LukeTaylor的评论:我将<global-method-security>添加到webmvc-config.xml并删除mode="aspectj",它有效,我做了一些实验,仍然有一些问题:

1)它的工作原理只适用于ArticleController.java,ArticleController_Roo_Controller.aj中的@Secure标签仍然不起作用,是否与“挥动”有关? 2)你能解释一下为什么mode=aspectj让它变得混乱吗?

1 个答案:

答案 0 :(得分:11)

正如@Luke Taylor在评论中所建议的那样,需要在dispatcher-servlet.xml(本例中为webmvc-config.xml)文件中定义标记<sec:global-method-security/>。并且不需要具有属性mode="aspectj"

感谢。