Spring Security-如何启用方法安全注释? [英] Spring Security - how I can enable Method Security annotations?

查看:80
本文介绍了Spring Security-如何启用方法安全注释?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

StackOverflow上有很多类似的问题,但是我找不到任何答案:(

There is lot of similar questions at StackOverflow, but I can't find any answered :(

我有类似的web.xml:

I have web.xml like:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/spring-security.xml
    </param-value>
</context-param>

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

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<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>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

并尝试配置带有注释的方法安全性.如我所见,它必须由<sec:global-method-security pre-post-annotations="enabled"/>完成,与其他组件放置在相同的上下文中,就我而言,spring-web.xml.所以我有以下spring-web.xml:

and trying to configure method security with annotations. As I see it must be done by <sec:global-method-security pre-post-annotations="enabled"/>, placed at same context as other components, spring-web.xml at my case. So I have following spring-web.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.0.xsd"
        default-autowire="byName">

    <context:component-scan base-package="com.cleanplates.apiserv"/>
    <sec:global-method-security pre-post-annotations="enabled"/>

</beans>

spring-security.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:sec="http://www.springframework.org/schema/security"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.0.xsd">

    <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">
        <sec:filter-chain-map path-type="ant">
            <sec:filter-chain pattern="/**"
                              filters="
                                usernamePasswordProcessingFilter,
                                rememberMeFilter,
                                anonymousProcessingFilter,
                                exceptionTranslationFilter,
                                filterInvocationInterceptor"/>
        </sec:filter-chain-map>
    </bean>

    <bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <bean class="org.springframework.security.access.vote.RoleVoter"/>
            </list>
        </property>
    </bean>

    <bean id="anonymousProcessingFilter"
          class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">
        <property name="key" value="********"/>
        <property name="userAttribute">
            <bean class="org.springframework.security.core.userdetails.memory.UserAttribute">
                <property name="authoritiesAsString">
                    <list>
                        <value>ROLE_ANONYMOUS</value>
                    </list>
                </property>
                <property name="password" value="none"/>
            </bean>
        </property>
    </bean>

    <bean id="usernamePasswordProcessingFilter" class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
        <property name="filterProcessesUrl" value="/auth/password"/>
        <property name="usernameParameter" value="username"/>
        <property name="passwordParameter" value="password"/>
        <property name="authenticationManager" ref="authenticationManager"/>
    </bean>

    <bean id="rememberMeFilter" class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">
        <property name="rememberMeServices" ref="rememberMeServices"/>
        <property name="authenticationManager" ref="authenticationManager" />
    </bean>

    <bean id="rememberMeServices" class="org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices">
        <property name="userDetailsService" ref="myUserDetailsService"/>
        <property name="key" value="*******"/>
        <property name="alwaysRemember" value="true"/>
    </bean>

    <bean id="rememberMeAuthenticationProvider" class="org.springframework.security.authentication.RememberMeAuthenticationProvider">
        <property name="key" value="******"/>
    </bean>

    <bean id="exceptionTranslationFilter" class="org.springframework.security.web.access.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint">
            <bean class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>
        </property>
    </bean>

    <bean id="filterInvocationInterceptor"
        class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="securityMetadataSource">
            <sec:filter-security-metadata-source>
              <sec:intercept-url pattern="/**" access="ROLE_ANONYMOUS,ROLE_USER" method="GET"/>
              <sec:intercept-url pattern="/**" access="ROLE_ADMIN" method="POST"/>
              <sec:intercept-url pattern="/**" access="ROLE_ADMIN" method="PUT"/>
              <sec:intercept-url pattern="/**" access="ROLE_ADMIN" method="DELETE"/>
            </sec:filter-security-metadata-source>
        </property>
        <property name="accessDecisionManager" ref="accessDecisionManager"/>
    </bean>

    <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">
        <property name="providers">
            <list>
                <bean class="org.springframework.security.authentication.AnonymousAuthenticationProvider">
                    <property name="key" value="***"/>
                </bean>
                <bean class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
                    <property name="saltSource">
                        <bean class="org.springframework.security.authentication.dao.ReflectionSaltSource">
                            <property name="userPropertyToUse" value="salt"/>
                        </bean>
                    </property>
                    <property name="userDetailsService" ref="myUserDetailsService"/>
                    <property name="passwordEncoder" ref="passwordEncoder"/>
                </bean>
            </list>
        </property>
    </bean>

    <bean id="myUserDetailsService" class=".UserDetailsServiceImpl">
    </bean>

    <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder">
    </bean>

</beans>

添加<sec:global-method-security后所有控制器停止工作的问题.而且我在日志中有以下内容:

The problem that after adding <sec:global-method-security all controllers stop working. And I have following in logs:

PageNotFound:noHandlerFound:947 - No mapping found for HTTP request with URI [/some/page] in DispatcherServlet with name 'spring'

当我删除此global-security元素时,一切正常.如果我将其添加到spring-security.xml-没有任何变化.似乎没有使用它,因为任何人都可以使用带有@PreAuthorize("hasRole('ROLE_ADMIN')")(或任何其他角色)注释的方法.

Everything is working when i remove this global-security element. If i'm adding it into spring-security.xml - nothing changes. Seems that it's not used, because methods annotated with @PreAuthorize("hasRole('ROLE_ADMIN')") (or any other role) are accessible by anyone.

PS我正在使用Spring 3.0.5.RELEASE和Spring Security 3.0.5.RELEASE

PS I'm using Spring 3.0.5.RELEASE and Spring Security 3.0.5.RELEASE

推荐答案

启用<sec:global-method-security>后,spring security将为控制器创建代理.在这种情况下,spring-mvc在bean上找不到像@RequestMapping这样的注释.如果要在控制器上使用安全注释,则应提取控制器的接口并在其上放置mvc注释. Spring文档包含有关此内容的以下注释:

After you enable <sec:global-method-security> spring security creates proxies for your controllers. spring-mvc can't find annotations like @RequestMapping on bean in this case. If you want to use security annotations on your controllers you should extract interface of controller and put mvc annotations on it. Spring documentation contains following note about this:

注意:使用控制器接口(例如,用于AOP代理)时,请确保一致地放置所有您的映射注释-如@RequestMapping@SessionAttributes-在控制器接口上,而不是在实现类上.

NOTE: When using controller interfaces (e.g. for AOP proxying), make sure to consistently put all your mapping annotations - such as @RequestMapping and @SessionAttributes - on the controller interface rather than on the implementation class.

这篇关于Spring Security-如何启用方法安全注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆