2011-07-05 185 views
5

我有一個使用彈簧安全的應用程序。在我的註冊過程中,一個新的用戶實體會持續使用HASHED密碼,包含激活令牌的電子郵件將發送給用戶。單擊此令牌可將用戶導向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()); 
} 

的問題是,它是否被創建時的用戶實體密碼字段已散列。所以我能想到的唯一的另一個選擇是將不需要的密碼作爲請求參數傳遞給servelet(討厭!)

我錯過了什麼,有沒有另一種預先驗證用戶的方式?

感謝

+1

我被這裏愚笨,用戶點擊激活鏈接,我們已經看了他很清楚我們有一個有效的用戶,所以沒有需要使用authenticationManager重新對其進行身份驗證,因此在創建令牌時不需要使用憑據,只需按如下所示創建它即可:PreAuthenticatedAuthenticationToken token = new PreAuthenticatedAuthenticationToken( p,null,p.getAuthorities()); –

+0

另一個類似的問題(和答案)可以在這裏找到:http://stackoverflow.com/a/12057327/26510 –

+1

@ClintonBosch你可以寫評論作爲答案並接受它 – fglez

回答

3

用戶點擊激活鏈接,我們已經看過他,所以顯然我們有一個有效的用戶,所以沒有必要與authenticationManager等重新進行身份驗證他沒有必要創建令牌時使用的憑據,只需創建它,如下所示:

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

如果我理解你正確地SOA可以幫助你。

您不需要重定向到登錄頁面,而是調用登錄用戶的服務。駐留在控制器(或服務層上的某個位置)的任何與登錄相關的邏輯應該移動到「down '並由您的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(), "")); 
+0

爲什麼負分? – Simeon