我有一个使用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(讨厌!)
我是否遗漏了某些内容,是否有另一种预先验证用户身份的方式?
由于
答案 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(), ""));