Spring Security-'global-method-security'不起作用 [英] Spring Security - 'global-method-security' does not work

查看:164
本文介绍了Spring Security-'global-method-security'不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是Spring& amp;的新手。 Spring Security Framework,并尝试保护使用Spring Security v3.1.4在最新的稳定Glassfish构建上运行的Java EE 7 REST App。

I am a newbie regarding Spring & Spring Security Frameworks and trying to secure a Java EE 7 REST App running on latest stable Glassfish build using Spring Security v3.1.4.

一切都很好,但是我无法使全球方法安全性发挥作用!这是我的配置,任何帮助将不胜感激。

Everything is fine but i cannot manage to make 'global-method-security' work! Here are my configs, any help would be greatly appreciated.

web.xml:

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

<filter>
    <filter-name>filterChainProxy</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
    <filter-name>filterChainProxy</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

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

Spring应用程序上下文已配置为进行预身份验证,如下所示:

Spring application context is configured for pre-authentication and looks like:

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
        <property name="alwaysUseJndiLookup" value="true" />
    </bean>

    <bean id="filterChainProxy" class="org.springframework.security.web.FilterChainProxy">
        <sec:filter-chain-map request-matcher="ant">
            <sec:filter-chain pattern="/api/authentication" filters="none"/>
            <sec:filter-chain pattern="/**" filters="sif,requestHeaderAuthFilder,logoutFilter,etf,fsi"/>
        </sec:filter-chain-map>
    </bean>

    <bean id="sif" class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>

    <sec:authentication-manager alias="authenticationManager">
        <sec:authentication-provider ref='preAuthenticatedAuthenticationProvider'/>
    </sec:authentication-manager>

    <bean id="preAuthenticatedAuthenticationProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService">
            <bean id="userDetailsServiceWrapper"
                  class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <property name="userDetailsService" ref="preAuthenticatedUserDetailsService"/>
            </bean>         
        </property>
    </bean>

    <bean id="preAuthenticatedUserDetailsService"
          class="org.someUserDetailsService"/>

    <bean id="requestHeaderAuthFilder" class="org.springframework.security.web.authentication.preauth.RequestHeaderAuthenticationFilter">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="principalRequestHeader" value="sometoken"/>      
    </bean>

    <bean id="preAuthenticatedProcessingFilterEntryPoint"
          class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"/>

    <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
        <constructor-arg value="/"/>
        <constructor-arg>
            <list>
                <bean class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>
            </list>
        </constructor-arg>
    </bean>

    <bean id="servletContext" class="org.springframework.web.context.support.ServletContextFactoryBean"/>

    <bean id="etf" class="org.springframework.security.web.access.ExceptionTranslationFilter">
        <property name="authenticationEntryPoint" ref="preAuthenticatedProcessingFilterEntryPoint"/>
    </bean>

    <bean id="httpRequestAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="allowIfAllAbstainDecisions" value="false"/>
        <property name="decisionVoters">
            <list>
                <ref bean="roleVoter"/>
                <ref bean="authenticatedVoter"/>
            </list>
        </property>
    </bean>

    <bean id="fsi" class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">
        <property name="authenticationManager" ref="authenticationManager"/>
        <property name="accessDecisionManager" ref="httpRequestAccessDecisionManager"/>      
        <property name="securityMetadataSource">
            <sec:filter-security-metadata-source use-expressions="true">
                <!--<sec:intercept-url  pattern="/api/authentication" access="permitAll"/>-->
                <sec:intercept-url pattern="/**" access="isAuthenticated()"/>
            </sec:filter-security-metadata-source>
        </property>

    </bean>

    <bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter"/>
    <bean id="authenticatedVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter"/>

    <bean id="securityContextHolderAwareRequestFilter" class="org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter"/>  

以下是Spring ACL配置:

And following is the Spring ACL Configuration:

<sec:global-method-security             
        pre-post-annotations="enabled">
        <sec:expression-handler ref="expressionHandler" />
     </sec:global-method-security>


    <bean id="expressionHandler"             class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
        <property name="permissionEvaluator" ref="aclPermissionEvaluator" />
    </bean>

    <bean name="aclPermissionEvaluator"
          class="org.CustomPermissionEvaluator">
        <constructor-arg name="aclService" ref="aclService" />
        <property name="sidRetrievalStrategy" ref="someSidRetrievalStrategy" />
    </bean>   

    <bean id="lookupStrategy"
          class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
        <constructor-arg name="dataSource" ref="dataSource" />
        <constructor-arg name="aclCache" ref="aclCache" />
        <constructor-arg name="aclAuthorizationStrategy" ref="aclAuthorizationStrategy" />
        <constructor-arg name="auditLogger" ref="auditLogger" />
    </bean>

     <bean id="aclCache"
          class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
        <constructor-arg>
            <bean class="org.springframework.cache.ehcache.EhCacheFactoryBean">
                <property name="cacheManager">
                    <bean class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" />
                </property>
                <property name="cacheName" value="aclCache" />
            </bean>
        </constructor-arg>
    </bean>

    <bean id="aclAuthorizationStrategy"
          class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
        <constructor-arg name="auths">
            <list>
                <!-- authority for taking ownership -->
                <bean
                    class="org.springframework.security.core.authority.GrantedAuthorityImpl">
                    <constructor-arg value="ROLE_ADMIN" />
                </bean>
                <!-- authority to modify auditing -->
                <bean
                    class="org.springframework.security.core.authority.GrantedAuthorityImpl">
                    <constructor-arg value="ROLE_ADMIN" />
                </bean>
                <!-- authority to make general changes -->
                <bean
                    class="org.springframework.security.core.authority.GrantedAuthorityImpl">
                    <constructor-arg value="ROLE_ADMIN" />
                </bean>
            </list>
        </constructor-arg>
        <property name="sidRetrievalStrategy" ref="someSidRetrievalStrategy"/>
    </bean>

    <bean id="someSidRetrievalStrategy" class="org.SomeSidRetrievalStrategyImpl"/>

    <bean id="auditLogger"
          class="org.springframework.security.acls.domain.ConsoleAuditLogger" />


    <jee:jndi-lookup 
        id="dataSource" 
        jndi-name="springacl" /> 


    <bean id="aclService" name="aclService"
          class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
        <constructor-arg name="dataSource" ref="dataSource" />
        <constructor-arg name="lookupStrategy" ref="lookupStrategy" />
        <constructor-arg name="aclCache" ref="aclCache" />
        <property name="sidIdentityQuery" value="select currval(pg_get_serial_sequence('acl_sid', 'id'))" />
        <property name="classIdentityQuery" value="select currval(pg_get_serial_sequence('acl_class', 'id'))" />
    </bean>

我想应用权限检查的方法如下:

And the method i want to apply permission check looks like:

    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @PreAuthorize("hasPermission(#id, 'read')")
    public Project getProject(@PathParam("id") Long id) {
    }



我在哪里弄错了?

推荐答案

我解决了这个问题,所以我想在这里分享详细信息,以帮助其他人搜索SS的全局安全功能可能无法正常工作的原因。

I solved the problem so i want to share details here to help the others searching for the reasons why global security feature of SS might be not working.

感谢 Arten Bilan 为我指明了正确的方向。我的问题的直接答案可能是:如果您想保护未定义为Spring Beans的代码,则应使用 AspectJ自动代理(mode = aspectj)。但是,您可能需要像我一样做更多工作。

Thanks to Arten Bilan for pointing me to the right direction. The direct answer of my question might be: if you want to secure your code which are not defined as Spring Beans, you should use "AspectJ auto-proxying" (mode="aspectj"). However, you may need more to make it work, as i did.

问题是,要启用Aspectj,您应该使用 AnnotationSecurityAspect 来自 spring-security-aspects 模块,如此处。特别是卢克·泰勒的帖子对我很有帮助。

The thing is, to enable aspectj, you should woven your code with the AnnotationSecurityAspect from the spring-security-aspects module as discussed here. Especially Luke Taylor's post was helpful to me.

要做到这一点,您应该使用Aspectj编译器来编译代码。如果您现在正在使用 Maven ,则以下配置可能会有所帮助(如):

To make this happen, you should compile your code using aspectj compiler. If you are using Maven as me doing now, following configurations may be helpful (as discussed here):

首先使用模式Aspectj进行设置:

First set using mode aspectj:

    <sec:global-method-security             
        pre-post-annotations="enabled"
        mode="aspectj"
        proxy-target-class="true">
        <sec:expression-handler ref="expressionHandler" />
    </sec:global-method-security>

为spring-security-aspects模块添加依赖项:

Add dependency for spring-security-aspects module:

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-aspects</artifactId>
            <version>3.1.4.RELEASE</version>
        </dependency>

最后添加以下maven插件和配置以进行编译时编织:

And finally add following maven plugin and configurations for compile time weaving:

        <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.4</version>
                <configuration>
                    <showWeaveInfo>true</showWeaveInfo>
                    <source>1.7</source>
                    <target>1.7</target>
                    <Xlint>ignore</Xlint>
                    <complianceLevel>1.7</complianceLevel>
                    <encoding>UTF-8</encoding>
                    <verbose>false</verbose>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework.security</groupId>
                            <artifactId>spring-security-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjrt</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>${aspectj.version}</version>
                    </dependency>
                </dependencies>
            </plugin>

这为我完成了工作。

这篇关于Spring Security-'global-method-security'不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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