SecurityContextHolder.getContext().getAuthentication() 返回 null

Posted

技术标签:

【中文标题】SecurityContextHolder.getContext().getAuthentication() 返回 null【英文标题】:SecurityContextHolder.getContext().getAuthentication() returning null 【发布时间】:2014-04-07 03:14:36 【问题描述】:

我想使用以下代码从 spring Security 中手动绕过用户:

User localeUser = new User();
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(localeUser ,null, localeUser .getAuthorities());
SecurityContext securityContext = SecurityContextHolder.getContext();
        securityContext.setAuthentication(auth);
        // Create a new session and add the security context.
        HttpSession session = request.getSession(true);
        session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
return "dummyLogin";

虚拟登录页面(由图块处理)在内部调用同一控制器中的不同请求映射,我试图在其中获得类似这样的身份验证。

SecurityContextHolder.getContext().getAuthentication()

我在哪里得到空值?

【问题讨论】:

您将一个空的 User 对象传递给 UsernamePasswordAuthenticationToken 构造函数。可能这就是你得到 null 的原因。 也是一个空密码(我认为这也是非法的)。也许如果你显示堆栈跟踪? password 可以为空,我宁愿在创建会话后检查会话是否相同,并且在运行 getAuthentication 的代码中。记录你的 session.getId() 来检查它。 您是否只想为某些特定页面或特定用户或全部绕过安全性? 我想绕过该特定会话 ID(用户)的所有页面 【参考方案1】:

所以,我发现了真正的问题! 问题是我在 security-context.xml 中用 security="none" 标记了整个控制器。 所以,当它从第一个链接反弹到第二个链接时,它没有传递任何安全上下文!! 抱歉,麻烦各位了。

【讨论】:

帮助我解决了我的问题,我将某些 url 模式放在忽略配置中,结果是这些控制器中的安全上下文为空,从忽略配置中删除使该控制器变得安全,最终获得安全上下文为想要的【参考方案2】:

附加答案:如果您想获取非安全 url 的登录用户详细信息,则可以将它们添加到安全 url 并分配为“permitAll”,如下所示:

<http>
    //...

    <intercept-url pattern="/your/url/**" access="permitAll"/>

    //...
</http>

然后,您将能够检查登录用户是否已登录或获取凭据。

【讨论】:

【参考方案3】:

您的 localUser 为 null。因此身份验证变为 null。因此未将身份验证对象添加到安全上下文中。

请看文档

http://docs.spring.io/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/core/userdetails/User.html

最好有一个customUserDetailsS​​ervice

public class CustomUserDetailsService implements UserDetailsService 

//implement the method which return a UserDetails Object
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException 

那么你可以使用

    UserDetails userDetails= customUserDetailsService.loadUserByUsername("name"); 
Authentication authentication= new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()) ; 
SecurityContextHolder.getContext().setAuthentication(authentication);

【讨论】:

localUser 不为空!它是应用程序的自定义用户对象,在初始化时自行在其中创建了 ID 和详细信息。【参考方案4】:

试试这个:

Authentication authentication=SecurityContextHolder.getContext().getAuthentication();
localeUser .setUserNm(authentication.getName());

【讨论】:

你不必评论它。相反,您可以添加您的 commnet 来回答

以上是关于SecurityContextHolder.getContext().getAuthentication() 返回 null的主要内容,如果未能解决你的问题,请参考以下文章