弹簧安全自动登录

时间:2011-07-05 10:25:15

标签: java servlets spring-security

我有一个使用spring-security的应用程序。在我的注册过程中,新的用户实体将使用HASHED密码保留,包含激活令牌的电子邮件将发送给用户。单击此标记会将用户定向到UserActivationServlet,UserActivationServlet通过令牌查找用户,激活用户并将其重定向到应用程序。我想自动将用户登录到应用程序中,并将此方法包含在我的servlet中以执行此操作

    private void authenticateUserAndSetSession(HttpServletRequest request, User u) {
    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(
            u.getUsername(), u.getPassword()); //PROBLEM: THIS PASSWORD IS HASHED

    // generate session if one doesn't exist
    request.getSession();

    token.setDetails(new WebAuthenticationDetails(request));
    Authentication authenticatedUser = authenticationManager.authenticate(token);

    SecurityContextHolder.getContext().setAuthentication(authenticatedUser);
    request.getSession().setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY,
            SecurityContextHolder.getContext());
}

这里的问题是User实体上的密码字段在创建时已经过哈希处理。因此,我能想到的唯一其他选择是将未散列的密码作为请求参数传递给servelet(讨厌!)

我是否遗漏了某些内容,是否有另一种预先验证用户身份的方式?

由于

2 个答案:

答案 0 :(得分:3)

用户点击了激活链接,我们已经查看了他,因此我们有一个有效的用户,因此无需使用authenticationManager重新验证他,因此无需使用凭据创建令牌,只需按如下方式创建:

PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken( p, null, p.getAuthorities());

答案 1 :(得分:0)

如果我理解正确SOA可以帮到你。

您无需重定向到登录页面,而是调用记录用户的服务。驻留在控制器(或服务层上方某处)的任何登录相关逻辑都应该“向下”移动并由您的servlet使用。

该服务可能类似于:

public interface LoginService {
    // this will be called from the login page
    public void login(String username, String hashedPass);

    // this will only be visible to other services
    // you can secure it with AOP and Spring security's method security
    public void login(String username);
}

然后你可以从你的servlet中调用loginService.login(username);

或者在您的确切情况下,在没有密码的情况下传递您的令牌:

loginService.login(new UsernamePasswordAuthenticationToken(u.getUsername(), ""));