程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> JSP和Struts解決用戶退出問題

JSP和Struts解決用戶退出問題

編輯:關於JSP

在一個有密碼保護的Web應用中,正確處理用戶退出過程並不僅僅只需調用HttpSession的invalidate()方法。現在大部分浏覽器上都有後退和前進按鈕,允許用戶後退或前進到一個頁面。如果在用戶在退出一個Web應用後按了後退按鈕浏覽器把緩存中的頁面呈現給用戶,這會使用戶產生疑惑,他們會開始擔心他們的個人數據是否安全。許多Web應用強迫用戶退出時關閉整個浏覽器,這樣,用戶就無法點擊後退按鈕了。還有一些使用javascript,但在某些客戶端浏覽器這卻不一定起作用。這些解決方案都很笨拙且不能保證在任一情況下100%有效,同時,它也要求用戶有一定的操作經驗。

這篇文章以示例闡述了正確解決用戶退出問題的方案。作者Kevin Le首先描述了一個密碼保護Web應用,然後以示例程序解釋問題如何產生並討論解決問題的方案。文章雖然是針對JSP頁面進行闡述,但作者所闡述的概念很容易理解切能夠為其他Web技術所采用。最後作者展示了如何用Jakarta Struts優雅地解決這一問題。

大部分Web應用不會包含象銀行賬戶或信用卡資料那樣機密的信息,但一旦涉及到敏感數據,我們就需要提供一類密碼保護機制。舉例來說,一個工廠中工人通過Web訪問他們的時間安排、進入他們的訓練課程以及查看他們的薪金等等。此時應用SSL(Secure Socket Layer)有點殺雞用牛刀的感覺,但不可否認,我們又必須為這些應用提供密碼保護,否則,工人(也就是Web應用的使用者)可以窺探到工廠中其他雇員的私人機密信息。

與上述情形相似的還有位處圖書館、醫院等公共場所的計算機。在這些地方,許多用戶共同使用幾台計算機,此時保護用戶的個人數據就顯得至關重要。設計良好編寫優秀的應用對用戶專業知識的要求少之又少。

我們來看一下現實世界中一個完美的Web應用是如何表現的:一個用戶通過浏覽器訪問一個頁面。Web應用展現一個登陸頁面要求用戶輸入有效的驗證信息。用戶輸入了用戶名和密碼。此時我們假設用戶提供的身份驗證信息是正確的,經過了驗證過程,Web應用允許用戶浏覽他有權訪問的區域。用戶想退出時,點擊退出按鈕,Web應用要求用戶確認他是否則真的需要退出,如果用戶確定退出,Session結束,Web應用重新定位到登陸頁面。用戶可以放心的離開而不用擔心他的信息會洩露。另一個用戶坐到了同一台電腦前,他點擊後退按鈕,Web應用不應該出現上一個用戶訪問過的任何一個頁面。事實上,Web應用在第二個用戶提供正確的驗證信息之前應當一直停留在登陸頁面上。

通過示例程序,文章向您闡述了如何在一個Web應用中實現這一功能。

JSP示例

為了更為有效地闡述實現方案,本文將從展示一個示例應用logoutSampleJSP1中碰到的問題開始。這個示例代表了許多沒有正確解決退出過程的Web應用。logoutSampleJSP1包含了下述jsp頁面:login.jsp, home.jsp, secure1.jsp, secure2.jsp, logout.jsp, loginAction.jsp, and logoutAction.jsp。其中頁面home.jsp, secure1.jsp, secure2.jsp, 和logout.jsp是不允許未經認證的用戶訪問的,也就是說,這些頁面包含了重要信息,在用戶登陸之前或者退出之後都不應該出現在浏覽器中。login.jsp包含了用於用戶輸入用戶名和密碼的form。logout.jsp頁包含了要求用戶確認是否退出的form。loginAction.jsp和logoutAction.jsp作為控制器分別包含了登陸和退出代碼。

第二個示例應用logoutSampleJSP2展示了如何解決示例logoutSampleJSP1中的問題。然而,第二個應用自身也是有疑問的。在特定的情況下,退出問題還是會出現。

第三個示例應用logoutSampleJSP3在第二個示例上進行了改進,比較完善地解決了退出問題。

最後一個示例logoutSampleStruts展示了Struts如何優美地解決登陸問題。

注意:本文所附示例在最新版本的Microsoft Internet Explorer (IE), Netscape Navigator, Mozilla, FireFox和Avant浏覽器上測試通過。

Login action

Brian Pontarelli的經典文章《J2EE Security: Container Versus Custom》討論了不同的J2EE認證途徑。文章同時指出,HTTP協議和基於form的認證並未提供處理用戶退出的機制。因此,解決途徑便是引入自定義的安全實現機制。

自定義的安全認證機制普遍采用的方法是從form中獲得用戶輸入的認證信息,然後到諸如LDAP (lightweight directory access protocol)或關系數據庫的安全域中進行認證。如果用戶提供的認證信息是有效的,登陸動作往HttpSession對象中注入某個對象。HttpSession存在著注入的對象則表示用戶已經登陸。為了方便讀者理解,本文所附的示例只往HttpSession中寫入一個用戶名以表明用戶已經登陸。清單1是從loginAction.jsp頁面中節選的一段代碼以此闡述登陸動作:

Listing 1
//...
//initialize RequestDispatcher object; set forward to home page by default
RequestDispatcher rd = request.getRequestDispatcher("home.jsp");
//Prepare connection and statement
rs = stmt.executeQuery("select password from USER where userName = '" + userName + "'");
if (rs.next()) {
 //Query only returns 1 record in the result set; only 1
 password per userName which is also the primary key
 if (rs.getString("password").equals(password)) { //If valid password
  session.setAttribute("User", userName); //Saves username string in the session object
 }
 else { //Password does not match, i.e., invalid user password
  request.setAttribute("Error", "Invalid password.");
  rd = request.getRequestDispatcher("login.jsp");
 }
} //No record in the result set, i.e., invalid username
else {
 request.setAttribute("Error", "Invalid user name.");
 rd = request.getRequestDispatcher("login.jsp");
}
}
//As a controller, loginAction.jsp finally either forwards to "login.jsp" or "home.jsp"
rd.forward(request, response);
//...

本文所附示例均以關系型數據庫作為安全域,但本文所闡述的觀點對任何類型的安全域都是適用的。

Logout action

退出動作就包含了簡單的刪除用戶名以及對用戶的HttpSession對象調用invalidate()方法。清單2是從loginoutAction.jsp頁面中節選的一段代碼以此闡述退出動作:

Listing 2
//...
session.removeAttribute("User");
session.invalidate();
//...

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved