2015-03-30 65 views
0

我有一個Web應用程序,我想阻止多次用戶登錄(從同一機器上的不同瀏覽器或不同的機器)。防止多用戶登錄 - HttpSessionBindingListener

我閱讀了關於HttpSessionBindingListener的內容,並試圖使我的登錄servlet和我的用戶Bean實現所需的解決方案。不幸的是,它只有當我第二次在同一瀏覽器上登錄(在不同的標籤頁中)時纔有效,但如果我改變瀏覽器(在同一臺機器上),它不再工作。

代碼如下。

用戶的Bean就擺在會議成功登錄後,在

public class BeanUtente implements HttpSessionBindingListener { 

private String username; 
private String gruppo; 

public boolean ruoloPresente(String nomeRuolo) { 
    //se il gruppo dell'utente è uguale a quello richiesto dal filtro 
    if (this.gruppo.equals(nomeRuolo)) 
     return true; 
    else 
     return false; 
} 

public void valueBound(HttpSessionBindingEvent argo) { 
    System.out.println("Value Bound Called, " + argo.getValue() + " isNewSession: " + argo.getSession().isNew()); 
} 

public void valueUnbound(HttpSessionBindingEvent argo) { 
    System.out.println("Value UnBound Called, " + argo.getValue() + " isNewSession: " + argo.getSession().isNew()); 
} 

public String toString() { 
    return "Username is: " + username; 
} 

public String getUsername() { 
    return username; 
} 

public void setUsername(String username) { 
    this.username = username; 
} 

public String getGruppo() { 
    return gruppo; 
} 

public void setGruppo(String gruppo) { 
    this.gruppo = gruppo; 
} 

}

登錄的servlet

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

    Db db = null; 
    PreparedStatement ps = null; 
    ResultSet rs = null; 

    try { 
     response.setHeader("Cache-Control","no-cache,no-store,must-revalidate"); 
     response.setHeader("Pragma","no-cache"); 
     response.setDateHeader("Expires", 0); 

     Locale locale = request.getLocale(); 
     ResourceBundle labels = ResourceBundle.getBundle("risorse.label", locale); 

     String urlLoginOk = getInitParameter("urlLoginOk"); 
     String urlLoginKo = getInitParameter("urlLoginKo"); 

     String username = request.getParameter("username"); 
     String password = request.getParameter("password"); 

     db = new Db(); 
     db.apriConnessione(); 

     String sql = "SELECT gruppo FROM Utenti WHERE username=? AND password=SHA2(?, 512)"; 

     ps = db.getConnection().prepareStatement(sql); 
     ps.setString(1, username); 
     ps.setString(2, password); 
     rs = ps.executeQuery(); 

     //login OK 
     if(username != null && password != null && rs.next()) { 
      BeanUtente beanUtente = new BeanUtente(); 
      beanUtente.setUsername(username); 
      beanUtente.setGruppo(rs.getString("gruppo")); 

      HttpSession sess = request.getSession(); 
      sess.setAttribute("beanUtente", beanUtente); 

      request.getRequestDispatcher(urlLoginOk).forward(request, response); 
     } 
     //login KO 
     else { 
      request.setAttribute("errore", labels.getString("loginFallito")); 
      request.getRequestDispatcher(urlLoginKo).forward(request, response); 
     } 

    } 
    catch(Exception e) { 
     e.printStackTrace(); 
    } 
    finally { 
     try { 
      if(!ps.isClosed()) 
       ps.close(); 
      if(!rs.isClosed()) 
       rs.close(); 
     } 
     catch (SQLException sqle) { 
      sqle.printStackTrace(); 
     } 
     catch (Exception e) { 
      e.printStackTrace(); 
     } 
     finally { 
      if(db.getConnection() != null) 
       db.chiudiConnessione(); 
     } 
    } 

} 

這裏是日誌。 當我首次登錄時,我得到:

*Value Bound Called, Username is: pi isNewSession: false* 

當我從同一個瀏覽器登錄,第二次,我得到:

*Value Bound Called, Username is: pi isNewSession: false 
Value UnBound Called, null isNewSession: false* 

因此,似乎未綁定的方法正確調用。 但是,如果我從其他瀏覽器登錄,第三次在同一臺機器上,我得到:

*Value Bound Called, Username is: pi isNewSession: false* 

也就是不受約束的方法還沒有被調用。

你能幫我理解我的錯誤在哪裏嗎? 我想我必須明確地調用session.removeAttribute(「beanUtente」)但是何時/何處?

預先感謝任何幫助:)

回答

0

爲了避免從多個瀏覽器登錄,我不認爲,這樣HttpSessionBindingListener將工作,因爲新的瀏覽器,它會創建新的會話。

您必須保存狀態在後端針對特定用戶,讓說userId爲每個用戶,可在cache/DB,有一次他登錄,並從cache/DB刪除它,一旦他退出,

所以當用戶登錄做如下。 Object user = getUser(userId);

如果(用戶!= NULL){// 用戶已經登錄,只是返回自定義消息 } 其他{// 允許用戶登錄 }上logout

與之相似的userIdcache/user刪除。

+0

嗨,問題是當用戶關閉瀏覽器而不註銷。我需要一種方法來在會話/上下文中超時用戶bean。 – Francesco 2015-03-31 17:18:12

+0

無法理解你的問題? – RE350 2015-03-31 17:21:55

+0

假設在第一次登錄後,我將userID放入上下文或DB中,並且我有一個註銷servlet,如果用戶單擊調用,則會從上下文/ DB中刪除userID。如果user1正確註銷,則沒有問題。 user1在沒有註銷的情況下關閉瀏覽器時出現問題;在這種情況下,如果user1嘗試再次登錄到應用程序,則登錄servlet將返回錯誤消息,因爲user1的userID已經存在於上下文/數據庫中。所以,我需要一種方法,從上一次操作起經過預定​​的時間後,從上下文/數據庫中刪除用戶ID。 – Francesco 2015-03-31 17:56:47

相關問題