我有一個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」)但是何時/何處?
預先感謝任何幫助:)
嗨,問題是當用戶關閉瀏覽器而不註銷。我需要一種方法來在會話/上下文中超時用戶bean。 – Francesco 2015-03-31 17:18:12
無法理解你的問題? – RE350 2015-03-31 17:21:55
假設在第一次登錄後,我將userID放入上下文或DB中,並且我有一個註銷servlet,如果用戶單擊調用,則會從上下文/ DB中刪除userID。如果user1正確註銷,則沒有問題。 user1在沒有註銷的情況下關閉瀏覽器時出現問題;在這種情況下,如果user1嘗試再次登錄到應用程序,則登錄servlet將返回錯誤消息,因爲user1的userID已經存在於上下文/數據庫中。所以,我需要一種方法,從上一次操作起經過預定的時間後,從上下文/數據庫中刪除用戶ID。 – Francesco 2015-03-31 17:56:47