我在部署在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的想法(很奇怪),或者有一些模糊的配置,或者使用某些依赖项? 谢谢你的帮助。
答案 0 :(得分:5)
最后,经过一天的不同尝试,我认为我解决了它。
在我整合AOP的测试中,我使用了一个教程,它定义了一个过于通用的切入点(正则表达式,如。*),这意味着我的托管bean的所有方法都是候选者,包括Spring-security和boum : - (
定义更具体的切入点(基本上基于包名称)可以避免启动应用程序时出错。
这是一个愚蠢的错误,但也许这个答案会帮助其他人。