《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 其他 > 業(yè)界動(dòng)態(tài) > 借助Session對(duì)象實(shí)現(xiàn)Web應(yīng)用的用戶身份識(shí)別

借助Session對(duì)象實(shí)現(xiàn)Web應(yīng)用的用戶身份識(shí)別

2009-01-06
作者:李利,王秀峰

1?引言

??? 通過瀏覽器操作的簡(jiǎn)易性和實(shí)現(xiàn)的方便性,使得基于B/S結(jié)構(gòu)的Web應(yīng)用模式日漸流行;在Web應(yīng)用環(huán)境中,特別是多角色用戶情況下,不同的用戶擁有的操作權(quán)限不同,用戶的身份識(shí)別非常重要。本文對(duì)Web應(yīng)用用戶身份識(shí)別的難點(diǎn)做了簡(jiǎn)單剖析,并從應(yīng)用程序的角度實(shí)現(xiàn)了用戶的身份認(rèn)證。

2?用戶身份識(shí)別的難點(diǎn)——HTTP協(xié)議的無狀態(tài)性

??? HTTP協(xié)議(即超文本傳輸協(xié)議,Hyper Text Transfer Protocol)是一個(gè)應(yīng)用層的網(wǎng)絡(luò)協(xié)議,采用客戶-服務(wù)器模式,用來發(fā)送客戶請(qǐng)求的服務(wù)器上的資源。Web應(yīng)用程序的用戶通過瀏覽器進(jìn)行操作,以瀏覽器作為客戶端采用HTTP協(xié)議同Web服務(wù)器進(jìn)行交互,完成相應(yīng)的工作,由此可見,HTTP協(xié)議是Web應(yīng)用程序的重要基礎(chǔ)之一。

??? 每個(gè)Web站點(diǎn)都有一個(gè)服務(wù)器進(jìn)程,它在特定TCP端口(默認(rèn)80)上不斷監(jiān)聽,以便發(fā)現(xiàn)是否有瀏覽器向它發(fā)出連接建立請(qǐng)求;一旦監(jiān)聽到連接建立請(qǐng)求并建立了TCP連接之后,瀏覽器就向服務(wù)器發(fā)出瀏覽某個(gè)頁面的請(qǐng)求,服務(wù)器接著就返回所請(qǐng)求的頁面作為響應(yīng);發(fā)送完響應(yīng)后,服務(wù)器關(guān)閉TCP連接。服務(wù)器處理下一個(gè)請(qǐng)求與上一個(gè)請(qǐng)求沒有任何關(guān)系,對(duì)于HTTP服務(wù)器而言各個(gè)請(qǐng)求都是一樣的,不會(huì)保留各次處理時(shí)的信息,這就是HTTP協(xié)議的無狀態(tài)性。

??? HTTP的無狀態(tài)性既是優(yōu)點(diǎn),也是缺點(diǎn),協(xié)議原本的設(shè)計(jì)在于共享資源,“無狀態(tài)”的設(shè)計(jì)較有效率也容易實(shí)現(xiàn),很適于它的典型應(yīng)用。但對(duì)基于Web的應(yīng)用,卻很不方便,特別是對(duì)擁有各種角色、權(quán)限的多用戶系統(tǒng)來說,可能要求對(duì)用戶的權(quán)限進(jìn)行區(qū)分,不同部門、不同角色能夠查看的頁面不同,對(duì)同一頁面的操作權(quán)限也可能要做區(qū)分,這就要求對(duì)用戶的身份進(jìn)行驗(yàn)證,通過驗(yàn)證的用戶還要保留其身份標(biāo)識(shí),以維護(hù)對(duì)相關(guān)聯(lián)頁面的操作權(quán)限。因?yàn)镠TTP協(xié)議本身不維護(hù)請(qǐng)求之間的狀態(tài)信息,若僅僅通過協(xié)議本身,服務(wù)器無法判斷各請(qǐng)求之間的關(guān)聯(lián)性,也就是說,我們盡管可以使用戶進(jìn)入Web應(yīng)用的默認(rèn)頁面為登陸頁面,讓用戶輸入用戶登陸名及密碼等信息以實(shí)現(xiàn)用戶身份驗(yàn)證,然后再通過鏈接或其它機(jī)制轉(zhuǎn)到其它相關(guān)頁面,但是如果不采取其它措施,用戶即使不從登陸頁面進(jìn)入也可以通過輸入U(xiǎn)RL的方式對(duì)網(wǎng)站上其它頁面進(jìn)行不受限制的訪問。因而,能夠識(shí)別用戶的身份、識(shí)別一系列遠(yuǎn)程客戶的請(qǐng)求是從同一個(gè)客戶處發(fā)出的,是建立有效的基于Web的應(yīng)用程序的關(guān)鍵。

3?解決之道——善用會(huì)話(Session)對(duì)象

??? 會(huì)話可以認(rèn)為是某個(gè)用戶和服務(wù)器之間的一系列相關(guān)的交互,這個(gè)交互會(huì)持續(xù)一段時(shí)間。對(duì)于單個(gè)用戶而言,會(huì)話過程的開始以用戶開始訪問某個(gè)網(wǎng)站為標(biāo)志,會(huì)話過程的結(jié)束以用戶結(jié)束對(duì)該網(wǎng)站的訪問為標(biāo)志。不同的用戶對(duì)應(yīng)著不同的會(huì)話過程,不同的會(huì)話過程之間互不干涉,互不影響。

??? 按對(duì)象的術(shù)語講,一個(gè)會(huì)話可以看作是一個(gè)對(duì)象,它駐留在服務(wù)器上的應(yīng)用程序中并受應(yīng)用程序的影響。一旦在服務(wù)器上建立了一個(gè)會(huì)話,一個(gè)稱為Session ID 的唯一標(biāo)識(shí)符就與此會(huì)話相關(guān)聯(lián)。每一個(gè)訪問網(wǎng)站的用戶在服務(wù)器端可以擁有自己唯一的一個(gè)會(huì)話對(duì)象,此會(huì)話對(duì)象為此用戶所獨(dú)享,即此會(huì)話對(duì)象同用戶有一一對(duì)應(yīng)的關(guān)系,用戶只能檢索自己的會(huì)話對(duì)象,而不能訪問其它用戶的會(huì)話對(duì)象;并且通過session對(duì)象的設(shè)置屬性的方法(setAttribute)可以將其它對(duì)象綁定到此會(huì)話對(duì)象,相應(yīng)的通過session對(duì)象的取得屬性的方法(getAttribute)可以檢索綁定到此會(huì)話對(duì)象的其它對(duì)象。

??? 注意到會(huì)話是客戶和服務(wù)器之間一一對(duì)應(yīng)的聯(lián)系,這一點(diǎn)非常重要,我們可以通過這個(gè)聯(lián)系將用戶的身份信息綁定到會(huì)話對(duì)象上,解決身份認(rèn)證和權(quán)限區(qū)分問題。

4?簡(jiǎn)單示例

??? 下面,我們借助session對(duì)象,通過采用JSP+JavaBean+數(shù)據(jù)庫的方式實(shí)現(xiàn)一個(gè)用戶認(rèn)證的簡(jiǎn)單示例。

41? Web應(yīng)用程序結(jié)構(gòu)

??? Web應(yīng)用的用戶界面結(jié)構(gòu)如下圖所示,用戶首先進(jìn)入登陸頁面 /set/login.htm ,在其中輸入用戶ID和密碼;在 /set/login.jsp中進(jìn)行校驗(yàn),若校驗(yàn)通過,則在session保存用戶身份信息,并根據(jù)用戶所屬部門將頁面導(dǎo)向相應(yīng)部門主頁面,否則,將頁面導(dǎo)向登陸頁面重新輸入用戶ID和密碼;對(duì)于需進(jìn)行身份驗(yàn)證的頁面,從session對(duì)象中檢索用戶身份信息,如果能檢索到,說明用戶已經(jīng)得到身份驗(yàn)證,反之,若檢索不到用戶身份信息,說明用戶還未經(jīng)過身份驗(yàn)證(可能是通過在瀏覽器地址欄輸入U(xiǎn)RL的方式直接進(jìn)入該頁的),則將頁面導(dǎo)向到登陸頁面;若通過認(rèn)證的用戶擁有操作此頁面的權(quán)限,則允許操作,否則,顯示權(quán)限錯(cuò)誤信息。

42? JavaBean?

???? 本實(shí)現(xiàn)中,需要用到如下幾個(gè)JavaBean(特殊的類) :

??? User:即用戶類,表示一個(gè)登陸到網(wǎng)站的用戶,具有用戶編號(hào)、密碼、部門、角色等屬性已及對(duì)這些屬性進(jìn)行存取的相應(yīng)方法。

??? UserManager類:用戶管理員類,對(duì)用戶合法性進(jìn)行校驗(yàn)。實(shí)現(xiàn)代碼如下:

package wxf.set;

import java.sql.*;

public class UserManager{ //用戶管理員類,用來通過查詢數(shù)據(jù)庫對(duì)用戶驗(yàn)證

?????? public User checkUser(String userid,String password){

????????????? /**通過查詢數(shù)據(jù)庫,如果存在用戶編號(hào)為userid并且密碼為password

????????????? ?*的用戶則構(gòu)造一個(gè)User 類的對(duì)象,并對(duì)此User類的對(duì)象設(shè)置userid,

????????????? ?*department,role 等屬性,然后返回此對(duì)象;

????????????? ?*如果不存在編號(hào)為userid并且密碼為password

????????????? ?*的用戶則返回null

??????? */

?????? }

}

43? 登陸驗(yàn)證頁面(login.jsp

<%@ page language="java" %>

<%@ page import="wxf.set.*"%>

<%

? String userid=request.getParameter("userid");

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

? UserManager aUM=new UserManager();

? //校驗(yàn)用戶編號(hào)和密碼,確定是否為合法用戶

User aUser=aUM.checkUser(userid,password);

? if(aUser!=null){ //是合法用戶

? ??? session.setAttribute("user",aUser);? //將aUser對(duì)象綁定到session對(duì)象

? ??? if(aUser.getDepartment().equals("dp1")){

? ?????????? //如果用戶屬于部門1則轉(zhuǎn)到部門1的主界面

? ?????????? response.sendRedirect(response.encodeRedirectUrl("/set/dp1/index.jsp"));

? ??? }

? ??? else if(aUser.getDepartment().equals("dp2")){

? ?????????? //如果用戶屬于部門2則轉(zhuǎn)到部門2的主界面

? ?????????? response.sendRedirect(response.encodeRedirectUrl("/set/dp2/index.jsp"));

? ??? }

? }

??else{

? ??? //不是合法用戶,則轉(zhuǎn)到登陸界面

? ??? response.sendRedirect(response.encodeRedirectUrl("/set/login.htm"));

? }

%>

44? 身份驗(yàn)證代碼

??? 非法用戶在未通過身份驗(yàn)證的情況下,可能通過鍵入U(xiǎn)RL非法訪問某個(gè)特定JSP文件,為此,必須對(duì)要保護(hù)的頁面安排身份檢查代碼。因?yàn)閷?duì)每個(gè)登陸到網(wǎng)站的用戶,都可以擁有自己獨(dú)享的唯一的session對(duì)象,每個(gè)用戶只能訪問自己的session對(duì)象;因此,可以在要求認(rèn)證的JSP文件的開頭安排如下代碼:從session對(duì)象中檢索用戶(User)對(duì)象,因?yàn)橛脩羧绻菑牡顷戫撁孢M(jìn)入并且是合法用戶,則在登陸時(shí)已經(jīng)將用戶的身份信息封裝成User對(duì)象綁定到session對(duì)象上了,所以如果能檢索到,說明用戶是經(jīng)過了合法認(rèn)證進(jìn)到該頁面的,否則,說明用戶還未經(jīng)過認(rèn)證,需要將頁面轉(zhuǎn)到認(rèn)證頁面;如果經(jīng)過認(rèn)證,則再從用戶對(duì)象中檢索其角色(role)屬性,若允許此角色的用戶訪問該頁,則顯示頁面內(nèi)容,否則,顯示權(quán)限錯(cuò)誤信息。示例代碼如下:

?????? <%

???? //從session對(duì)象中檢索名稱為user的對(duì)象

? ???User theUser=(User)session.getAttribute("user");?????

???? if(theUser==null){?????? //如果不能能檢索到用戶對(duì)象

? ??? ????response.sendRedirect(response.encodeRedirectUrl("/set/login.htm");

? ???}

??? else{?????? //如果存在用戶對(duì)象則取得用戶的角色信息

? ??? ??String theRole=theUser.getRole();

? ??? ??//假使角色為11的用戶可以訪問

? ??? ??if(!theRole.equals("11")){??

? ?????????? out.println("對(duì)不起,您無權(quán)訪問此頁!");

? ??? ??}

? ??? ??else{

? ?????????? //顯示頁面內(nèi)容????

? ??? ??}

? ??}

%>

5 總結(jié)

??? Web應(yīng)用的關(guān)鍵是要識(shí)別用戶,HTTP協(xié)議的無狀態(tài)性使服務(wù)器無法跟蹤用戶操作的相關(guān)性;JSP內(nèi)建的session對(duì)象,是每個(gè)登陸到網(wǎng)站的用戶獨(dú)自擁有的,我們可以借助session對(duì)象保存用戶的身份信息,對(duì)涉及需要特殊身份才能訪問的頁面設(shè)置身份校驗(yàn)代碼,檢索用戶session對(duì)象中的身份信息進(jìn)行校驗(yàn),可以較好實(shí)現(xiàn)用戶身份識(shí)別。

參考文獻(xiàn)?

【1】謝希仁.計(jì)算機(jī)網(wǎng)絡(luò)(第二版).北京:電子工業(yè)出版社,1999.4

【2】Karl Avedal, Danny Ayers 等.JSP編程指南.北京:電子工業(yè)出版社,2001

【3】黃理,洪亮,等.JSP高級(jí)編程.北京:北京希望電子出版社, 2001

【4】丁振凡.ASP應(yīng)用系統(tǒng)中用戶認(rèn)證設(shè)計(jì).計(jì)算機(jī)時(shí)代,1999(8).

本站內(nèi)容除特別聲明的原創(chuàng)文章之外,轉(zhuǎn)載內(nèi)容只為傳遞更多信息,并不代表本網(wǎng)站贊同其觀點(diǎn)。轉(zhuǎn)載的所有的文章、圖片、音/視頻文件等資料的版權(quán)歸版權(quán)所有權(quán)人所有。本站采用的非本站原創(chuàng)文章及圖片等內(nèi)容無法一一聯(lián)系確認(rèn)版權(quán)者。如涉及作品內(nèi)容、版權(quán)和其它問題,請(qǐng)及時(shí)通過電子郵件或電話通知我們,以便迅速采取適當(dāng)措施,避免給雙方造成不必要的經(jīng)濟(jì)損失。聯(lián)系電話:010-82306118;郵箱:aet@chinaaet.com。