我创建了一个@Aspect类,并尝试获取像..
这样的主体对象SecurityContextHolder.getContext().getAuthentication() .getPrincipal()
在我的方面类中,但我得到空指针。我的方面没有可用的上下文。任何指针。?
答案 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)
如果执行方面,可能会发生这种情况......
...在非servlet线程上,即一些后台线程或在请求处理期间已启动的线程。在后一种情况下,您可以通过将SecurityContextHolder
配置为将上下文存储在可继承 ThreadLocal
中来解决问题,该生成线程也可以访问该文件(请参阅javadoc有关详情)。
...在负责的安全过滤器对请求进行身份验证之前。启用安全类的日志记录,或为调试会话设置一些断点以检查这是否是问题。
答案 2 :(得分:0)
确保Spring安全过滤器链涵盖此代码。
SecurityContextHolder
将由一个Spring Security过滤器(SecurityContextPersistenceFilter
)填充。因此,如果未针对当前请求/线程触发安全过滤器链,则SecurityContextHolder
为空。用SecurityContextPersistenceFilter.doFilter(...)
方法制作制动点。如果未触发,请在安全xml文件中进行适当的更改。