SecurityContextHolder.getContext()在AspectJ类中不起作用

时间:2013-08-14 10:43:57

标签: spring spring-security aop

我创建了一个@Aspect类,并尝试获取像..

这样的主体对象
SecurityContextHolder.getContext().getAuthentication() .getPrincipal()

在我的方面类中,但我得到空指针。我的方面没有可用的上下文。任何指针。?

3 个答案:

答案 0 :(得分:7)

SecurityContextHolder将给定的SecurityContext与当前执行线程相关联。由于方面截取单独线程上的方法(不太确定), 因此您可能需要更改安全上下文持有者策略 。由于SecurityContextHolder提供了一系列委托给SecurityContextHolderStrategy实例的静态方法。 SecurityContextHolder的目的是提供一种方便的方法来指定应该用于给定JVM的策略。

如果没有定义策略,SecurityContextHolder类将默认使用MODE_THREADLOCAL。

因此您需要将策略更改为MODE_INHERITABLETHREADLOCAL。

有两种方法可以指定所需的策略模式。第一种是通过SYSTEM_PROPERTY上的系统属性指定它。第二种是调用 setStrategyName(String) before using the class

在Spring中,您需要在应用程序上下文中定义bean,如下所示:

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass"><value>org.springframework.security.core.context.SecurityContextHolder</value></property>
    <property name="targetMethod"><value>setStrategyName</value></property>
    <property name="arguments">
        <list>
            <value>MODE_INHERITABLETHREADLOCAL</value>
        </list>
    </property>
</bean>

答案 1 :(得分:1)

如果执行方面,可能会发生这种情况......

  1. ...在非servlet线程上,即一些后台线程或在请求处理期间已启动的线程。在后一种情况下,您可以通过将SecurityContextHolder配置为将上下文存储在可继承 ThreadLocal中来解决问题,该生成线程也可以访问该文件(请参阅javadoc有关详情)。

  2. ...在负责的安全过滤器对请求进行身份验证之前。启用安全类的日志记录,或为调试会话设置一些断点以检查这是否是问题。

答案 2 :(得分:0)

确保Spring安全过滤器链涵盖此代码。

SecurityContextHolder将由一个Spring Security过滤器(SecurityContextPersistenceFilter)填充。因此,如果未针对当前请求/线程触发安全过滤器链,则SecurityContextHolder为空。用SecurityContextPersistenceFilter.doFilter(...)方法制作制动点。如果未触发,请在安全xml文件中进行适当的更改。