2012-03-22 46 views
6

我使用JSF2.0和Java EE6上的JBoss AS 7會話固定 - 登錄後刪除會議,並作出新的會話 - 但用戶則不會再

登錄我有一個LoginController.java這樣看:

@ManagedBean(name = "loginController") 
@SessionScoped 
public class LoginController implements Serializable{ 

    private static final long serialVersionUID = 1119172305268193508L; 

    @Inject 
    private UserProvider userProvider; 

    @PostConstruct 
    public void initNewUser() { 
     user = new User(); 
    } 

    private User user; 

    private String accountName; 

    private String password; 

    public String ownLogin() throws Exception { 

     HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance() 
       .getExternalContext().getRequest(); 


     if (accountName != null) { 
      try { 


       if (exists(accountName)) { 

        user = userProvider.findUserByAccountName(accountName); 

        if (verifyPassword(user, password)) { 

         userProvider.saveChangedUser(user); 


         // OWASP SAYS: after login, destroy the session make a new one 
         // a so called handover 
         // Destroy the session 
         FacesContext facesContext = FacesContext.getCurrentInstance(); 

         HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false); 
         if(session != null){ 
          session.invalidate(); 
         } 
         // create new session after logout 
         session = (HttpSession) facesContext.getExternalContext().getSession(true); 
        setLogin(true); 
      }     
    } 

/* some getters and setters */ 

} 

的OWASP說,出於安全原因,一個登錄會話應該被刪除後(參見:V3.7

我在這一點上做到這一點在我的代碼:

FacesContext facesContext = FacesContext.getCurrentInstance(); 

          HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false); 
          if(session != null){ 
           session.invalidate(); 
          } 
          // create new session after logout 
          session = (HttpSession) facesContext.getExternalContext().getSession(true); 

首先,我刪除舊的會話,然後我做一個新的會話。
在此之後,我設置了登錄真...

當然,在整個運行的代碼後,用戶沒有登錄,因爲LoginController中是在舊的會話範圍管理 - 在新的會話範圍有一個新的LoginController在沒有用戶的範圍內...

有什麼辦法,在創建後添加一個新的LoginController到新的會話?

或者什麼是常見的做法呢?

回答

4

當您使會話無效時,其所有屬性將在響應結束時被刪除。但是,您只能在僅保留舊會話的會話範圍的bean實例上設置登錄狀態。

您基本上需要手動重新創建會話範圍的bean,並在之後將其放入新會話中。

ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
externalContext.invalidateSession(); 
LoginController loginController = new LoginController(); 
loginController.setUser(user); 
externalContext.getSessionMap().put("loginController", loginController); 

(看馬,沒有醜女javax.servlet進口了!)

順便說一句,當你走這條路,你也可以只讓你LoginController視圖作用域的bean和處理User在只有會話。

ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
externalContext.invalidateSession(); 
externalContext.getSessionMap().put("user", user); 

(這將是可利用#{user}整個EL背景下,也是在管理性能;它不一定需要是一個JSF託管bean)

+0

並再次...謝謝你!這工作完美....如果我需要userProvider再次註銷...但如果我嘗試註銷,我做類似:'loggedIn = false; \t \t user.setLoggedIn(false); userProvider.saveChangedUser(user); ExternalContext externalContext = FacesContext.getCurrentInstance()。getExternalContext(); externalContext.invalidateSession();'然後userprovider是空的。我alsow嘗試將用戶提供程序也放在會話中,但不工作 - 之後,我錯誤,我不能再次登錄 - 因爲userProvider爲空... – Joerg 2012-03-22 22:19:22

+0

...好吧,我看到userProvider不是空的 - 但userProvider中的entityManager(以及@ @ Injected或'@ Produces'的其他所有內容都是空的) – Joerg 2012-03-22 23:11:57

+2

'@Inject'屬於CDI,不適用於JSF'@ ManagedBean',只能在CDI'@ Named' 。使'UserProvider'成爲'@ Stateless'並通過'@ EJB'注入它。 – BalusC 2012-03-22 23:13:23