2011-07-05 52 views
5

Tôi có một ứng dụng sử dụng bảo mật mùa xuân. Trong quá trình đăng ký của tôi, một thực thể người dùng mới được duy trì liên tục bằng mật khẩu HASHED, một email chứa mã thông báo kích hoạt được gửi tới người dùng. Nhấp vào mã thông báo này sẽ hướng người dùng đến UserActivationServlet tra cứu người dùng bằng mã thông báo, kích hoạt người dùng và chuyển hướng họ đến ứng dụng. Tôi muốn tự động đăng nhập người dùng vào ứng dụng và đã bao gồm phương pháp này trong servlet của tôi để làmĐăng nhập tự động với bảo mật mùa xuân

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()); 
} 

vấn đề này ở đây là rằng trường mật khẩu trên thực thể người dùng đã bị băm khi nó được tạo ra. Vì vậy, lựa chọn duy nhất khác mà tôi có thể nghĩ đến là chuyển mật khẩu chưa được chuyển đổi thành thông số yêu cầu tới servelet (khó chịu!)

Tôi đã bỏ lỡ điều gì đó, có cách nào khác để xác thực trước người dùng không?

Cảm ơn

+1

tôi đã là ngu ngốc đây, người dùng đã nhấp vào liên kết kích hoạt và chúng tôi đã xem xét anh ta rõ ràng là chúng tôi có một người dùng hợp lệ, vì vậy không có cần xác thực lại anh ta với authenticationManager và vì vậy không cần sử dụng thông tin đăng nhập khi tạo Mã thông báo, chỉ cần tạo thông tin xác thực như sau: Mã xác thực PreAuthenticatedAuthenticationToken = new PreAuthenticatedAuthenticationToken ( p, null, p.getAuthorities()); –

+0

một câu hỏi tương tự (và câu trả lời) có thể được tìm thấy ở đây: http://stackoverflow.com/a/12057327/26510 –

+1

@ClintonBosch Bạn có thể viết nhận xét dưới dạng câu trả lời và chấp nhận nó – fglez

Trả lời

3

Người dùng đã nhấp vào liên kết kích hoạt và chúng tôi đã nhìn anh ta lên như vậy rõ ràng chúng ta có một người dùng hợp lệ, vì vậy không có nhu cầu để tái xác nhận ông với authenticationManager và vì vậy không cần thiết phải sử dụng thông tin khi tạo Token, chỉ cần tạo ra nó như sau:

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

Nếu tôi hiểu chính xác SOA có thể giúp bạn.

Bạn không cần chuyển hướng đến trang đăng nhập, mà là gọi dịch vụ đăng nhập người dùng. Bất kỳ logic liên quan đến đăng nhập nào nằm trong bộ điều khiển (hoặc ở đâu đó trên lớp dịch vụ) phải được di chuyển xuống 'và được sử dụng bởi servlet của bạn.

Dịch vụ này có thể giống như thế:

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); 
} 

Sau đó, bạn có thể gọi loginService.login(username); từ servlet của bạn.

Hoặc trong trường hợp chính xác của bạn vượt qua thẻ của bạn không có mật khẩu:

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

Tại sao số điểm âm? – Simeon

Các vấn đề liên quan