用戶認證管理設計方案
2024-07-21 02:16:05
供稿:網友
網站運營seo文章大全提供全面的站長運營經驗及seo技術!
用戶認證管理設計方案
1 設計思路
為了設計一套具有較強可擴展性的用戶認證管理,需要建立用戶、角色和權限等數據庫表,并且建立之間的關系,具體實現如下。
1.1 用戶
用戶僅僅是純粹的用戶,用來記錄用戶相關信息,如用戶名、密碼等,權限是被分離出去了的。用戶(user)要擁有對某種資源的權限,必須通過角色(role)去關聯。
用戶通常具有以下屬性:
ü 編號,在系統中唯一。
ü 名稱,在系統中唯一。
ü 用戶口令。
ü 注釋,描述用戶或角色的信息。
1.2 角色
角色是使用權限的基本單位,擁有一定數量的權限,通過角色賦予用戶權限,通常具有以下屬性:
ü 編號,在系統中唯一。
ü 名稱,在系統中唯一。
ü 注釋,描述角色信息
1.3 權限
權限指用戶根據角色獲得對程序某些功能的操作,例如對文件的讀、寫、修改和刪除功能,通常具有以下屬性:
ü 編號,在系統中唯一。
ü 名稱,在系統中唯一。
ü 注釋,描述權限信息
1.4 用戶與角色的關系
一個用戶(user)可以隸屬于多個角色(role),一個角色組也可擁有多個用戶,用戶角色就是用來描述他們之間隸屬關系的對象。用戶(user)通過角色(role)關聯所擁有對某種資源的權限,例如
l 用戶(user):
userid username userpwd
1 張三 xxxxxx
2 李四 xxxxxx
……
l 角色(role):
roleid rolename rolenote
01 系統管理員 監控系統維護管理員
02 監控人員 在線監控人員
03 調度人員 調度工作人員
04 一般工作人員 工作人員
……
l 用戶角色(user_role):
userroleid userid roleid userrolenote
1 1 01 用戶“張三”被分配到角色“系統管理員”
2 2 02 用戶“李四”被分配到角色“監控人員”
3 2 03 用戶“李四”被分配到角色“調度人員”
……
從該關系表可以看出,用戶所擁有的特定資源可以通過用戶角色來關聯。
1.5 權限與角色的關系
一個角色(role)可以擁有多個權限(permission),同樣一個權限可分配給多個角色。例如:
l 角色(role):
roleid rolename rolenote
01 系統管理員 監控系統維護管理員
02 監控人員 在線監控人員
03 調度人員 調度工作人員
04 一般工作人員 工作人員
……
l 權限(permission):
permissionid permissionname permissionnote
0001 增加監控 允許增加監控對象
0002 修改監控 允許修改監控對象
0003 刪除監控 允許刪除監控對象
0004 察看監控信息 允許察看監控對象
……
l 角色權限(role_permission):
rolepermissionid roleid permissionid rolepermissionnote
1 01 0001 角色“系統管理員”具有權限“增加監控”
2 01 0002 角色“系統管理員”具有權限“修改監控”
3 01 0003 角色“系統管理員”具有權限“刪除監控”
4 01 0004 角色“系統管理員”具有權限“察看監控”
5 02 0001 角色“監控人員”具有權限“增加監控”
6 02 0004 角色“監控人員”具有權限“察看監控”
……
由以上例子中的角色權限關系可以看出,角色權限可以建立角色和權限之間的對應關系。
1.6 建立用戶權限
用戶權限系統的核心由以下三部分構成:創造權限、分配權限和使用權限。
第一步由creator創造權限(permission),creator在設計和實現系統時會劃分。利用存儲過程createpermissioninfo(@permissionname,@permissionnote)創建權限信息,指定系統模塊具有哪些權限。
第二步由系統管理員(administrator)創建用戶和角色,并且指定用戶角色(user-role)和角色權限(role-permission)的關聯關系。
1) administrator具有創建用戶、修改用戶和刪除用戶的功能:
l 存儲過程createuserinfo(@username,@userpwd)創建用戶信息;
l 存儲過程modifyuserinfo(@username,@userpwd)修改用戶信息;
l 存儲過程deleteuserinfo(@userid)刪除用戶信息;
2) administrator具有創建角色和刪除角色的功能:
l 存儲過程createroleinfo(@rolename,@rolenote)創建角色信息;
l 存儲過程deleteroleinfo(@roleid)刪除角色信息;
3)administrator具有建立用戶和角色、角色和權限的關聯關系功能:
l 存儲過程grantuserrole(@userid,@roleid,@userrolenote)建立用戶和角色的關聯關系;
l 存儲過程deleteuserrole(@userroleid)刪除用戶和角色的關聯關系;
l 存儲過程grantrolepermission(@roleid,@permissionid,@rolepermissionnote)建立角色和權限的關聯關系;
l 存儲過程deleterolepermission(@rolepermissionid)刪除角色和權限的關聯關系;
第三步用戶(user)使用administrator分配給的權限去使用各個系統模塊。利用存儲過程getuserrole(@userid, @userroleid output),getrolepermission(@roleid,@role-
-permissinid output)獲得用戶對模塊的使用權限。
1.7 用戶認證實現
當用戶通過驗證后,由系統自動生成一個128位的ticketid保存到用戶數據庫表中,建立存儲過程login(@userid,@userpwd,@ticketid output)進行用戶認證,認證通過得到一個ticketid,否則ticketid為null。其流程圖如下:
圖1 login流程圖
得到ticketid后,客戶端在調用服務端方法時傳遞ticketid,通過存儲過程judgeticketpermission(@ticketid,@permissionid)判斷ticketid對應的用戶所具有的權限,并根據其權限進行方法調用。
當用戶退出系統時,建立存儲過程logout(@userid)來退出系統。當用戶異常退出系統時,根據最后的登陸時間(lastsigntime)確定用戶的tickeid,建立存儲過程exceptionlogout(@userid,@lastsigntime)處理用戶的異常退出。
圖2 logout流程圖
webservice可以采用soapheader中寫入ticketid來使得ticketid從客戶端傳遞給服務端。.net remoting可以采用callcontext類來實現ticketid從客戶端傳遞給服務端。
2 數據庫設計
2.1 數據庫表
圖3 數據庫關系圖
2.2 數據庫表說明2.2.1 用戶表(static_user)
static_user
static_user字段名
詳細解釋
類型
備注
userid
路線編號
varchar(20)
pk
username
用戶名稱
varchar(20)
userpwd
用戶密碼
varchar(20)
lastsigntime
最后登陸時間
datatime
signstate
用戶登陸狀態標記
int
tickeid
驗證票記錄編號
varchar(128)
2.2.2 角色表(static_role)
static_role
static_user字段名
詳細解釋
類型
備注
roleid
角色編號
varchar(20)
pk
rolename
角色名稱
varchar(20)
rolenote
角色信息描述
varchar(20)
2.2.3 用戶-角色表(static_user_role)
static_user_role
static_user字段名
詳細解釋
類型
備注
userroleid
用戶角色編號
varchar(20)
pk
userid
用戶編號
varchar(20)
fk
roleid
角色編號
varchar(20)
fk
userrolenote
用戶角色信息描述
varchar(20)
2.2.4 權限表(static_permission)
static_permission
static_user字段名
詳細解釋
類型
備注
permissionid
編號
varchar(20)
pk
permissionname
權限名稱
varchar(20)
permissionnote
全息信息描述
varchar(20)
2.2.5 角色-權限表(static_role_permission)
static_role_permission
static_user字段名
詳細解釋
類型
備注
rolepermissionid
角色權限編號
varchar(20)
pk
roleid
角色編號
varchar(20)
fk
permissionid
權限編號
varchar(20)
fk
rolepermissionnote
角色權限信息描述
varchar(20)
3 .net技術概要
3.1 webservice soapheader
對 sql 數據庫執行自定義身份驗證和授權。在這種情況中,應向服務傳遞自定義憑據(如用戶名和密碼),并讓服務自己處理身份驗證和授權。 將額外的信息連同請求一起傳遞給 xml web 服務的簡便方法是通過 soap 標頭。為此,需要在服務中定義一個從 soapheader 派生的類,然后將服務的公共字段聲明為該類型。這在服務的公共合同中公開,并且當從 webserviceutil.exe 創建代理時可由客戶端使用,如下例所示:
using system.web.services;
using system.web.services.protocols;
// authheader class extends from soapheader
public class authheader : soapheader {
public string username;
public string password;
}
public class headerservice : webservice {
public authheader sheader;
...
}
服務中的每個 webmethod 都可以使用 soapheader 自定義屬性定義一組關聯的標頭。默認情況下,標頭是必需的,但也可以定義可選標頭。soapheader 屬性指定公共字段的名稱或者 client 或 server 類的屬性(本標題中稱為 headers 屬性)。在為輸入標頭調用方法前,webservice 設置 headers 屬性的值;而當方法為輸出標頭返回時,webservice 檢索該值。
[webmethod(description="this method requires a custom soap header set by the caller")]
[soapheader("sheader")]
public string securemethod() {
if (sheader == null)
return "error: please supply credentials";
else
return "user: " + sheader.username;
}
然后,客戶端在調用要求標頭的方法之前,直接在代理類上設置標頭,如下面的示例所示:
headerservice h = new headerservice();
authheader myheader = new authheader();
myheader.username = "username";
myheader.password = "password";
h.authheader = myheader;
string result = h.securemethod();
3.2 .net remoting的安全認證方式
callcontext提供與執行代碼路徑一起傳送的屬性集,callcontext是類似于方法調用的線程本地存儲的專用集合對象,并提供對每個邏輯執行線程都唯一的數據槽。數據槽不在其他邏輯線程上的調用上下文之間共享。當 callcontext 沿執行代碼路徑往返傳播并且由該路徑中的各個對象檢查時,可將對象添加到其中。當對另一個 appdomain 中的對象進行遠程方法調用時,callcontext 類將生成一個與該遠程調用一起傳播的 logicalcallcontext 實例。只有公開 ilogicalthreadaffinative 接口并存儲在 callcontext 中的對象被在 logicalcallcontext 中傳播到 appdomain 外部。不支持此接口的對象不在 logicalcallcontext 實例中與遠程方法調用一起傳輸。
callcontext.setdata方法存儲給定對象并將其與指定名稱關聯,callcontext.getdata方法從 callcontext 中檢索具有指定名稱的對象。
下面的代碼示例說明如何使用 setdata 方法將主體和標識對象傳輸到遠程位置以進行標識。
public class clientclass {
public static void
main
() {
genericidentity ident = new genericidentity("bob");
genericprincipal prpal = new genericprincipal(ident,
newstring[] {"level1"});
logicalcallcontextdata data =
new logicalcallcontextdata(prpal);
//enter data into the callcontext
callcontext.setdata("test data", data);
console.writeline(data.numofaccesses);
channelservices.registerchannel(new tcpchannel());
remotingconfiguration.registeractivatedclienttype(
typeof(helloserviceclass), "tcp://localhost:8082");
helloserviceclass service = new helloserviceclass();
if(service == null) {
console.writeline("could not locate server.");
return;
}
// call remote method
console.writeline();
console.writeline("calling remote object");
console.writeline(service.hellomethod("caveman"));
console.writeline(service.hellomethod("spaceman"));
console.writeline(service.hellomethod("bob"));
console.writeline("finished remote object call");
console.writeline();
//extract the returned data from the call context
logicalcallcontextdata returneddata =
(logicalcallcontextdata)callcontext.getdata("test data");
console.writeline(data.numofaccesses);
console.writeline(returneddata.numofaccesses);
}
}
下面的代碼示例說明如何使用 getdata 方法將主體和標識對象傳輸到遠程位置以進行標識。
using system;
using system.text;
using system.runtime.remoting.messaging;
using system.security.principal;
public class helloserviceclass : marshalbyrefobject {
static int n_instances;
int instancenum;
public helloserviceclass() {
n_instances++;
instancenum = n_instances;
console.writeline(this.gettype().name + " has been created.
instance # = {0}", instancenum);
}
~helloserviceclass() {
console.writeline("destroyed instance {0} of
helloserviceclass.", instancenum);
}
public string hellomethod(string name) {
//extract the call context data
logicalcallcontextdata data =
(logicalcallcontextdata)callcontext.getdata("test data");
iprincipal myprincipal = data.principal;
//check the user identity
if(myprincipal.identity.name == "bob") {
console.writeline("/nhello {0}, you are identified!",
myprincipal.identity.name);
console.writeline(data.numofaccesses);
}
else {
console.writeline("go away! you are not identified!");
return string.empty;
}
// calculate and return result to client
return "hi there " + name + ".";
}
}
4 詳細代碼設計
4.1 webservice代碼設計
webservice端代碼主要進行對數據庫的操作,建立起client操作數據庫所需要的方法,供client的端調用。
1)class userinfomng() 用戶信息管理類,其中包括方法:
l createuserinfo(string username string userpwd) 建立用戶信息,調用存儲過程createuserinfo(@username,@userpwd)
l modifyuserinfo(string username string userpwd) 修改用戶信息,調用存儲過程modifyuserinfo(@username,@userpwd)
l deleteuserinfo() 刪除用戶信息,調用存儲過程deleteuserinfo
(@userid)
2)class userauthentication() 用戶認證類,用來實現用戶角色、權限的設置,包括方法:
l createpermissioninfo(string permissionname string permissi-
-onnote) 建立權限信息,調用存儲過程createpermissioninfo
(@permissionname,@permissionnote)
l createroleinfo(string rolename string rolenote) 建立角色信息,調用存儲過程createroleinfo(@rolename,@rolenote)
l deleteroleinfo() 刪除角色信息,調用存儲過程deleteroleinfo
(@roleid)
l grantuserrole(string userid string roleid string userrolenote) 授予用戶角色,調用存儲過程grantuserrole(@userid,@roleid,
@userrolenote)
l deleteuserrole() 刪除用戶角色,調用存儲過程deleteuserrole
(@userroleid)
l grantrolepermission(string roleid string permissionid string rolepermissionnote) 授予角色權限,調用存儲過程grantrolepermission(@roleid,@permissionid,@rolepermissionnote)
l deleterolepermission() 刪除授予的角色權限,調用存儲過程
deleterolepermission(@rolepermissionid)
4.2 用戶認證代碼設計(client端)
client端調用webservice方法來進行數據庫訪問,client端代碼設計主要實現界面的功能,包括:權限設置、用戶管理、用戶授權管理和用戶認證管理
1)權限設置
class permissioninfomng() 用戶權限信息管理類,包括方法:
l createpermissioninfo() 建立權限信息
2)用戶管理
class userinfomng() 用戶信息管理類,包括方法:
l createuserinfo() 建立用戶信息
l modifyuserinfo() 修改用戶信息
l deleteuserinfo() 刪除用戶信息
3)用戶授權管理
class roleinfomng() 角色信息管理類,包括方法:
l createroleinfo() 建立角色信息
l deleteroleinfo() 刪除角色信息
class userrolemng() 用戶角色管理類,包括方法:
l grantuserrole() 授予用戶角色
l deleteuserrole() 刪除用戶角色
class rolepermissionmng() 角色權限管理類,包括方法
l grantrolepermission() 授予角色權限
l deleterolepermission() 刪除角色權限
4)用戶認證管理
class authentication() 用戶認證類,包括方法:
l login(string username string userpwd) 用戶登陸認證,用戶認證通過分配給用戶一個ticketid,否則ticketid則為null
l logout() 用戶正常退出
l exceptionlogout() 用戶異常退出