如何使用 Spring Security 3.1 以编程方式登录用户

Posted

技术标签:

【中文标题】如何使用 Spring Security 3.1 以编程方式登录用户【英文标题】:How to programmatically log user in with Spring Security 3.1 【发布时间】:2011-11-28 16:42:47 【问题描述】:

在 Spring 和 Spring Security 3.1 中以特定用户名以编程方式登录 Web 访问者的正确方法是什么?看来我在 2.5 下的操作方式发生了一些变化。我确信现在有更好的方法来做到这一点。

基本上,当我创建一个新用户时,我还需要同时登录。

【问题讨论】:

【参考方案1】:

创建一个Authentication(通常是UsernamePasswordAuthenticationToken)然后调用

SecurityContextHolder.getContext().setAuthentication(authentication)

【讨论】:

并将 UsernamePasswordAuthenticationToken 的密码设置为空字符串?对于我必须想象的如此普遍需要的东西来说,这似乎太不优雅了。现在有什么 webapp 在注册时不会自动登录?至少权限有限... 然后实现自己的Authentication,或者子类AbstractAuthenticationToken。 很好奇为什么还没有一种简单的,甚至是声明式的方式来以编程方式让人们登录?至少一个无密码的 AuthenticationToken .. 你不必使用空字符串,你可以使用他们注册的密码。 我想对于新用户注册的具体情况是有道理的,但与大多数网站一样,我不存储明文密码,即使我这样做也是不必要的查找。【参考方案2】:

这三行代码为我完成了工作:

        Authentication request = new UsernamePasswordAuthenticationToken( username, password );
    Authentication result = authenticationManager.authenticate( request );
    SecurityContextHolder.getContext().setAuthentication( result );

【讨论】:

我正在寻找一种以同样优雅的方式添加记住我功能的方法.... 你找到了记住我的解决方案吗? 这可能有解决方案:***.com/questions/7806921/…【参考方案3】:

如果您有兴趣这样做以进行测试,您可以这样做:

    UserDetails user = _userService.loadUserByUsername(username);
    TestingAuthenticationToken token = new TestingAuthenticationToken(user,null);
    SecurityContextHolder.getContext().setAuthentication(token);

用户服务是你实现 UserDetailsS​​ervice 的东西

【讨论】:

【参考方案4】:

您可以编写一个扩展 Spring 的 UsernamePasswordAuthenticationFiltercustom UsernamePasswordAuthenticationFilter

代码如下:

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetails;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CustomUsernamePasswordAuthenticationFilter extends UsernamePasswordAuthenticationFilter 
    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication authResult) throws IOException, ServletException 
        super.successfulAuthentication(request, response, authResult);
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authResult;
        WebAuthenticationDetails details = (WebAuthenticationDetails) token.getDetails();
        String address = details.getRemoteAddress();
        User user = (User) authResult.getPrincipal();
        String userName = user.getUsername();
        System.out.println("Successful login from remote address: " + address + " by username: "+ userName);
    

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException, ServletException 
        super.unsuccessfulAuthentication(request, response, failed);
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) failed.getAuthentication();
        WebAuthenticationDetails details = (WebAuthenticationDetails) token.getDetails();
        String address = details.getRemoteAddress();
        System.out.println("Failed login try from remote address: " + address);
    

【讨论】:

我不明白这如何解决注册时自动登录的问题。 这是你要找的东西吗:forum.springsource.org/showthread.php?28165-Automatic-login-after-user-registration 我不知道当局会自动使用authenticationManager.authenticate(token) 查找。谢谢。

以上是关于如何使用 Spring Security 3.1 以编程方式登录用户的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Spring Security 3.1 中使用 acl_entry 表中的掩码字段?

如何在 Spring Security 3.1 中进行没有身份验证和授权的并发会话控制

使用 Active Directory 的 Spring Security 3.1

Spring Security 3.1 活动目录认证

Spring Security 3.1 xsd 和 jars 不匹配问题

spring security 3.1 isAuthenticated() 不工作