Spring Security和AOP问题

时间:2014-08-09 08:44:14

标签: spring-security aspectj spring-aop

我在部署在Tomcat 7服务器上的Spring-Security应用程序中添加了AOP功能。 应用程序工作正常,因为我添加了AspectJ依赖项。

这是我在POM中的Maven依赖项:

<properties>
    <spring.framework.version>4.0.5.RELEASE</spring.framework.version>
    <spring.security.version>3.2.4.RELEASE</spring.security.version>
</properties>
<!-- Spring dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
            <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${spring.security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.framework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjtools</artifactId>
        <version>1.8.1</version>
    </dependency>
</dependencies>

在这里,我的Spring配置(至少是最相关的):

<security:global-method-security secured-annotations="enabled" />

<bean id="myAuthenticationDetailsSource"
    class="net.classnotfound.MyAuthenticationDetailsSource">
</bean>

<bean id="oracleLoginChecker"
    class="net.classnotfound.OracleLoginChecker">
</bean>

<bean id="ldapLoginChecker"
    class="net.classnotfound.LdapLoginChecker">
</bean>

<bean id="myAuthenticationProvider" class="net.classnotfound.MyAuthenticationProvider">
    <property name="loginCheckerMap">
        <map>
            <entry key="ORACLE" value-ref="oracleLoginChecker"/>
            <entry key="LDAP" value-ref="ldapLoginChecker"/>
        </map>
    </property>
</bean>

<bean id="loggerListener"
    class="org.springframework.security.authentication.event.LoggerListener" />

<security:authentication-manager
    alias="authenticationManager">
    <!-- create a custom AuthenticationProvider class to tune the login 
        process -->
    <security:authentication-provider
        ref="myAuthenticationProvider" />
</security:authentication-manager>

    <security:http auto-config="true" use-expressions="true">
    <security:intercept-url pattern="/faces/login/**" access="anonymous" />
    <security:intercept-url pattern="/faces/**"
        access="authenticated" />
    <security:form-login login-page="/faces/login/login.xhtml"
        authentication-failure-url="/faces/login/login.xhtml?error=1"
        default-target-url="/faces/index.xhtml"
        authentication-details-source-ref="myAuthenticationDetailsSource"
        username-parameter="username" password-parameter="password" />
</security:http>


<tx:annotation-driven />
<beans>
    <bean id="aroundAspect" class="net.classnotfound.AroundAdvice" />
    <aop:aspectj-autoproxy />
    <aop:config>
        <aop:aspect ref="aroundAspect">
            <aop:pointcut id="aroundPointCut" expression="@target(org.springframework.transaction.annotation.Transactional)" />
            <aop:around pointcut-ref="aroundPointCut" method="doBasicProfiling" />
        </aop:aspect>
    </aop:config>
</beans>

现在,当我启动Tomcat时,我遇到了这个错误:

[...]
Caused by: java.lang.NoSuchMethodException: com.sun.proxy.$Proxy34.isEraseCredentialsAfterAuthentication()
at java.lang.Class.getMethod(Class.java:1655)
at org.springframework.util.MethodInvoker.prepare(MethodInvoker.java:174)
at org.springframework.beans.factory.config.MethodInvokingFactoryBean.afterPropertiesSet(MethodInvokingFactoryBean.java:103)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
... 64 more

我google了一下,似乎JDK代理机制不能代理&#34;在接口级别定义的注释方法,我尝试使用以下命令调整我的配置类:

<aop:aspectj-autoproxy proxy-target-class="true"/>

但是现在,我有:

[...]
Caused by: java.lang.IllegalArgumentException: Cannot subclass final class class org.springframework.security.config.method.GlobalMethodSecurityBeanDefinitionParser$AuthenticationManagerDelegator
at org.springframework.cglib.proxy.Enhancer.generateClass(Enhancer.java:446)
at org.springframework.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
at org.springframework.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
at org.springframework.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
at org.springframework.cglib.proxy.Enhancer.createClass(Enhancer.java:317)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:57)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
... 34 more

我认为这是正常的,因为它是AspectJ的已知限制。

所以现在,我被困了,我是否必须放弃在同一个项目中使用Spring安全性和AOP的想法(很奇怪),或者有一些模糊的配置,或者使用某些依赖项? 谢谢你的帮助。

1 个答案:

答案 0 :(得分:5)

最后,经过一天的不同尝试,我认为我解决了它。

在我整合AOP的测试中,我使用了一个教程,它定义了一个过于通用的切入点(正则表达式,如。*),这意味着我的托管bean的所有方法都是候选者,包括Spring-security和boum : - (

定义更具体的切入点(基本上基于包名称)可以避免启动应用程序时出错。

这是一个愚蠢的错误,但也许这个答案会帮助其他人。