An Authentication object was not found in the SecurityContex 错误

An Authentication object was not found in the SecurityContex 异常最近正在使用spring security做函数

An Authentication object was not found in the SecurityContex 异常
最近正在使用spring security做函数安全性控制,如果通过访问页面的方式,我查看在调用方法的时候能够顺利进入@PreAuthorize中指定的验证函数返回 true or false 以判断是否具备访问权限。

可是目前我使用Spring 的 @Scheduled 进行一些定期的操作,也就是说在没有session的情况下,没有用户触发系统自己调用方法,可是当系统后台调用这个@Scheduled方法的时候,而在这个方法内部调用了一些通过@PreAuthorize控制了访问权限的方法,这样一来就出现如下异常,无法验证是否具备访问权限。很恼人。。

异常代码如下


Java code
org.springframework.security.authentication.AuthenticationCredentialsNotFoundException: An Authentication object was not found in the SecurityContext    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:325)    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:196)    at org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:64)    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)    at $Proxy40.refreshGlobalCacheStrategyMetrics(Unknown Source)    at org.sly.main.server.service.system.scheduling.MaintenanceServiceImpl.runRecreateStrategyMetricsCache(MaintenanceServiceImpl.java:85)    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)    at java.lang.reflect.Method.invoke(Method.java:597)    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)    at org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:80)    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)    at java.util.concurrent.FutureTask.run(FutureTask.java:138)    at java.lang.Thread.run(Thread.java:662)






我在网上找了很久,在spring官网也看到这个问题,可是没有给出具体解决方法

http://static.springsource.org/spring-security/site/faq.html#auth-exception-credentials-not-found 

摘取了相关的描述如下:

1.5. I get an exception with the message "An Authentication object was not found in the SecurityContext". What's wrong?

This is a another debug level message which occurs the first time an anonymous user attempts to access a protected resource, but when you do not have an AnonymousAuthenticationFilter in your filter chain configuration.

  DEBUG [ExceptionTranslationFilter] - Authentication exception occurred; redirecting to authentication entry point
  org.springframework.security.AuthenticationCredentialsNotFoundException:
  An Authentication object was not found in the SecurityContext
  at org.springframework.security.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:342)
  at org.springframework.security.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:254)


而在另一个页面给出了配置 AnonymousAuthenticationFilter
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/anonymous.html

说是要这么配置
XML code
<bean id="anonymousAuthFilter"    class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">  <property name="key" value="foobar"/>  <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS"/></bean><bean id="anonymousAuthenticationProvider"    class="org.springframework.security.authentication.AnonymousAuthenticationProvider">  <property name="key" value="foobar"/></bean> 






于是乎,我就在我的 application-security.xml 中做了如下配置,但是没有任何效果

XML code
    <beans:bean id="springSecurityFilterChain"        class="org.springframework.security.web.FilterChainProxy">        <security:filter-chain-map path-type="ant">            <security:filter-chain pattern="/**"                filters="anonymousAuthFilter" />        </security:filter-chain-map>    </beans:bean>    <!-- ///////////////////////////////////////// -->    <!-- ////for AnonymousAuthenticationFilter//// -->    <!-- ///////////////////////////////////////// -->    <beans:bean id="anonymousAuthFilter"        class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">        <beans:property name="key" value="foobar" />        <beans:property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />    </beans:bean>    <beans:bean id="anonymousAuthenticationProvider"        class="org.springframework.security.authentication.AnonymousAuthenticationProvider">        <beans:property name="key" value="foobar" />    </beans:bean>


[解决办法]
我这也碰到了相同的问题,有没有人可以解决啊,急啊!!!
[解决办法]
An Authentication object was not found in the SecurityContext。
没有在Security上下文中找到认证信息!

在spring security进行处理前,会经过一条过虑链处理(一系列filter),每个过滤器会进行一些必要的处理,其中就有一个将认证信息(当前用户认证信息)放入到SecurityContext(应该是个线程变量)中,后续才可以用这些信息进行鉴权处理(如lz描述的处理@PreAuthorize声明的方法)。

按照lz的说法,由 @Scheduled 进行一些定期的操作,这样是不会进过虑链处理,当然不会有Authentication,所以出错!
所以你应该考虑在由@Scheduled触发的线程中将Authentication放入到SecurityContext中!