Spring Security:身份验证返回 null
我按如下方式配置了一个 Spring bean 以返回 SecurityContext:
<bean id="securityContext" class="org.springframework.security.context.SecurityContextHolder"
factory-method="getContext">
</bean>
当我使用此 bean 时,Authentication 对象返回 null。
Authentication authentication = securityContext.getAuthentication();
GrantedAuthority[] authorities = authentication.getAuthorities();
上面的第二行导致 NPE。 这对我来说似乎很奇怪,因为以下代码按预期返回权限:
GrantedAuthority[] authorities =
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
基本上我试图消除对 SecurityContextHolder.getContext() 的静态调用以使我的代码更易于测试。
关于如何解决这个问题有什么想法吗? 为什么 Spring 返回的 SecurityContext 无法返回权限,而我自己的代码中的静态调用却可以?
仅供参考,我正在 Struts 2 Action 中执行代码。
I have configured a Spring bean as follows to return a SecurityContext:
<bean id="securityContext" class="org.springframework.security.context.SecurityContextHolder"
factory-method="getContext">
</bean>
When I use this bean the Authentication object returns null.
Authentication authentication = securityContext.getAuthentication();
GrantedAuthority[] authorities = authentication.getAuthorities();
The second line above causes an NPE. Which seems odd to me, as the following code returns the authorities as expected:
GrantedAuthority[] authorities =
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
Basically I'm trying to eliminate the static call to SecurityContextHolder.getContext() to make my code more testable.
Any thoughts on how to remedy this? Why is the SecurityContext returned by Spring not able to return the authorities while a static call from within my own code can?
FYI I am executing the code from within a Struts 2 Action.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
SecurityContextHolder.getContext() 返回与当前线程关联的上下文。 在 bean 实例化中,存储在 bean 中的上下文与应用程序运行时所需的上下文不同。 我认为不可能将上下文存储在 bean 中并一直使用它。
SecurityContextHolder.getContext() returns the context associated with the current thread. In bean instantiation the context stored in your bean is different than the context you need when your application is running. I don't think that it is possible to store the context in a bean and use this all the time.
您可以使用静态方法使代码可测试。 您只需要创建自己的 org.springframework.security.Authentication 实现,
因此在您的 JUnit 测试中...
在上面的示例中,“userDetails”是实现“UserDetails”的类,并且通常包装您的域 User 对象。
我的 TestAuthentication 类 - 希望这有帮助
You can make your code testable using the static approach. You simply need to create your own implementation of org.springframework.security.Authentication
So in your JUnit Test...
In the example above 'userDetails' is the class which implements 'UserDetails' and typically wraps your domain User object.
My TestAuthentication class - hope this helps
发生这种情况是因为您创建的 bean 没有定义范围,所以它基本上是一个单例。
要使其按您希望的方式工作,您需要将其设置为请求/会话范围。
It happens since the bean you created does not define scope- so it is basically a singleton.
To make it work as you wish you need to make it request/session scoped.
使用一个您可以注入默认供应商的供应商。
Use a supplier that you could inject with a default one perhaps.