2012-11-03 103 views
3

我對Java/Spring/MVC比較陌生。我希望有人能夠對此發表一些看法,因爲這個問題即將毀了另一個週末而沒有得到解決。春季安全,更改密碼後繞過登錄頁面

目前我工作的一個項目,實行一對夫婦的RFC的。每個RFC都有它自己的'挑戰',從更改休眠查詢和存儲過程到更小的文本更改以及向表單添加額外的字段。

我現在面臨的問題有(我認爲)做春天的安全性。

目前情況:
要登錄到應用程序,用戶通過登錄頁面(/user/login.jsp)顯示。輸入用戶名和密碼後,用戶將被髮送到歡迎頁面(/welcome/hello.jsp)。

如果用戶忘記了自己的密碼,他們使用,這將發送一封帶有鏈接的網頁的鏈接(/首頁/ NEWPASSWORD?代碼= XXX),可以輸入新的密碼。進入提交按鈕將執行一些驗證,將密碼保存在數據庫中,並在頁面上顯示「密碼已更改」消息。 要輸入應用程序,用戶現在必須使用新密碼登錄。

什麼客戶希望: 提交新密碼後,用戶應自動登錄時使用的新密碼,並重定向到/welcome/hello.jsp中

我在網上搜索,但沒有找到我正在尋找的場景(或者可能沒有認出它!)。

我以爲會做的伎倆:

我在WelcomeController這種方法,目前處理的新密碼:

@RequestMapping(method = RequestMethod.POST) 
public void newPassword(Model model, HttpSession httpSession, ModelAttribute(PASSWORD) Passwords password, BindingResult result) { 
    logger.debug("Posting password for new password"); 
    ScreenMessage message = null; 

    // 
    try { 
     // errors from initBinder - back to page 
     if (result.hasErrors()) { 
      return; 
     } 

     // Validate input: on error go back to form 
     passwordValidator.validate(password, result); 
     if (result.hasErrors()) { 
      return; 
     } 

     // Save password 
     passwordService.createNewOwnPassword(result, password); 
     if (result.hasErrors()) { 
      return; 
     } 

     // No errors 
     message = new ScreenMessage(); 
     message.setText(CHANGED); 
     message.setArg(THIS_PASSWORD, 0); 
     model.addAttribute(MESSAGE, message); 
     httpSession.setAttribute(ACTION_READ, Boolean.TRUE); 

     // Errors are fatal. 
    } catch (Exception e) { 
     logger.error("ERROR-CHANGE-password for user: " + password.getUser().getLoginName(), e); 
     result.reject( ERROR_FATAL, new Object[] { password}, ERROR_FATAL); 
    } finally { 
     model.addAttribute(PASSWORD, password); 
    } 
} 

我想我可以簡單地改變這個方法將它返回一個ModelAndView並使用重定向:

ModelAndView mav = new ModelAndView("redirect:/welcome/hello", (ModelMap) model); 
     return mav; 

但是:它使我送到/用戶/註冊,完全頁,我不想去......

可能方便的其他信息:

據我可以告訴應用程序使用Spring 2.5。

(我希望有關)我安全的applicationContext.xml的部分:

<!-- always-use-default-target="true" --> 
    <security:form-login login-page="/dyn/user/login" 
     login-processing-url="/dyn/user/j_spring_security_check" 
     default-target-url="/dyn/welcome/hello" 
     always-use-default-target="true" 
     authentication-failure-handler-ref="exceptionTranslationRouting" /> 

    <security:access-denied-handler error-page="/dyn/welcome/hello" /> 

    <security:logout logout-success-url="/dyn/user/logout" invalidate-session="true" /> 

是我重定向到/首頁/你好太簡單了還是我只是缺少一些小的想法?

回答

1

首先,你最好從移動網絡控制器的邏輯(我不喜歡密碼驗證),以專用密碼更改組件。這將允許您在邏輯上分離應用程序的各個部分。過濾也許? (更晚)或特殊服務?

其次,來看看春季安全的源代碼。根據我的經驗,我可以告訴你,只有瞭解它的體系結構(特別是過濾鏈)時,Spring Security中的任何定製纔是可能的。我會建議看看類AbstractAuthenticationProcessingFilter。 它負責在您的應用程序中提供用戶名和密碼時對用戶進行身份驗證。看看方法AbstractAuthenticationProcessingFilter.successfulAuthentication

此行該方法的設置,這使得登錄的用戶的安全上下文:

SecurityContextHolder.getContext().setAuthentication(authResult); 

參考authResult是Authentication類型。它是由例如UsernamePasswordAuthenticationToken實現的接口。以UsernamePasswordAuthenticationFilter.attemptAuthentication方法爲例,說明如何構建這樣的對象。

回到過濾器解決方案: 我個人會考慮實施我自己的過濾器,它將延長AbstractAuthenticationProcessingFilter。它將負責密碼更改。這樣,您就不必考慮成功驗證會話更改等事情。你只需要在你的XML中注入它。

綜上所述,被推薦看

類:

  • AbstractAuthenticationProcessingFilter
  • UsernamePasswordAuthenticationToken
  • UsernamePasswordAuthenticationFilter

你應該閱讀Spring Security的文檔,尤其是部分關於建築學,fi過濾鏈及其在認證用戶中的作用。

http://static.springsource.org/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#overall-architecture