3

我创建了一个@Aspect 类并尝试获取主体对象,例如..

SecurityContextHolder.getContext().getAuthentication() .getPrincipal()

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

4

3 回答 3

7

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

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

所以你需要将策略更改为 MODE_INHERITABLETHREADLOCAL。

有两种方法可以指定所需的策略模式。第一种是通过在 SYSTEM_PROPERTY 上键入的系统属性来指定它。第二种是在使用 class 之前调用setStrategyName(String)

在 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>
于 2013-09-24T15:05:49.463 回答
1

This could happen in case the aspect is executed...

  1. ...on a non-servlet thread, i.e. some background thread or one that has been started during request processing. In the latter case you can solve the problem by configuring the SecurityContextHolder to store the context in an inheritable ThreadLocal which spawned threads can access as well (see the javadoc for details).

  2. ...before the request gets authenticated by the responsible security filters. Enable logging for security classes, or set up some breakpoints for a debug session to check if this is the problem.

于 2013-08-14T11:39:57.217 回答
0

确保此代码被弹簧安全过滤器链覆盖。

SecurityContextHolder将由 Spring Security 过滤器 ( SecurityContextPersistenceFilter) 之一填充。因此,如果当前请求/线程未触发安全过滤器链,SecurityContextHolder则为空。SecurityContextPersistenceFilter.doFilter(...)在方法中做一个刹车点。如果它没有被触发,那么在您的安全 xml 文件中进行适当的更改。

于 2013-08-14T11:38:38.527 回答