解讀ASP.NET Portal Starter Kit(4)——角色身份認證篇
2024-07-10 12:56:11
供稿:網友
,歡迎訪問網頁設計愛好者web開發。
asp.net portal starter kit是采用的“基于窗體的身份驗證”的身份驗證模式。forms 身份驗證通常指這樣一個系統,在該系統中使用 http 客戶端重定向將未經身份驗證的請求重定向到 html 窗體。如果應用程序需要在登錄時通過 html 窗體收集自己的用戶憑據,那么選擇 forms 身份驗證就很好。用戶提供憑據并提交該窗體。如果應用程序對請求進行身份驗證,系統會發出一個 cookie,在其中包含用于重新獲取標識的憑據或密鑰。隨后發出在請求頭中具有該 cookie 的請求。asp.net 事件處理程序使用應用程序指定的任何驗證方法對這些請求進行身份驗證和授權。
數據庫設計:
在asp.net portal starter kit中存儲用戶角色相關的表有三個:用戶信息表(portal_users),角色信息表(portal_roles),用戶角色關系表(portal_userroles)。通過用戶角色關系表將用戶信息和角色信息管理起來,可實現一個用戶可有多種角色,一個角色也可以同時是多個用戶。三表之間的關系如下:
程序實現:
在asp.net portal starter kit中用戶登錄成功后以email為用戶標識名稱建立用戶標識時同時觸發global.asax.cs中的application_authenticaterequest事件,將登錄用戶的角色信息讀入context.user中。在desktopdefault.aspx根據portalsettings.activetab.authorizedroles(當前活動標簽的可訪問屬性)判斷是否可訪問該標簽的內容。如果可訪問則呈現該標簽下的用戶模塊,不能訪問就重定向到訪問錯誤頁(accessdenied.aspx)。在管理用戶是否可編輯用戶模塊信息時,是判斷用戶角色是否在模塊指定的可編輯角色(模塊的iseditable屬性)中。
關鍵代碼:
1、 根據用戶的email獲取用戶的角色(以string[]的形式返回,一項表示一個角色,一個用戶可有多個角色)(security.cs中)
public string[] getroles(string email)
{
// 訪問數據庫的幾步曲
sqlconnection myconnection = new sqlconnection(configurationsettings.appsettings["connectionstring"]);
sqlcommand mycommand = new sqlcommand("portal_getrolesbyuser", myconnection);
mycommand.commandtype = commandtype.storedprocedure;
sqlparameter parameteremail = new sqlparameter("@email", sqldbtype.nvarchar, 100);
parameteremail.value = email;
mycommand.parameters.add(parameteremail);
// 打開鏈接用sqldatareader執行查詢
sqldatareader dr;
myconnection.open();
dr = mycommand.executereader(commandbehavior.closeconnection);
// 讀取用戶的角色信息
arraylist userroles = new arraylist();
while (dr.read()) {
userroles.add(dr["rolename"]);
}
dr.close();
return (string[]) userroles.toarray(typeof(string));
}
2、 檢查當前角色是否在指定的角色中(security.cs中)
public static bool isinroles(string roles)
{
httpcontext context = httpcontext.current;
foreach (string role in roles.split( new char[] {';'} ))
{
//指定角色中有all users的也表示通過
if (role != "" && role != null && ((role == "all users") || (context.user.isinrole(role))))
{
return true;
}
}
return false;
}
3、登錄驗證代碼(signin.ascx.cs中)
private void signinbtn_click(object sender, system.web.ui.imageclickeventargs e)
{
// 通過usersdb類嘗試并驗證用戶是否合法
usersdb accountsystem = new usersdb();
string userid = accountsystem.login(email.text, portalsecurity.encrypt(password.text));
if ((userid != null) && (userid != ""))
{
// 為給定的 username 和 createpersistentcookie 創建身份驗證票,并將其附加到 cookie 的傳出響應的集合。它不執行重定向。
// 以email為用戶標識名稱建立用戶標識時同時觸發global.asax.cs中的application_authenticaterequest事件
formsauthentication.setauthcookie(email.text, remembercheckbox.checked);
// 從定向到起始頁
response.redirect(request.applicationpath);
}
else
{
message.text = "<" + "br" + ">登錄失??!" + "<" + "br" + ">";
}
}
4、global.asax.cs中的application_authenticaterequest事件
protected void application_authenticaterequest(object sender, eventargs e)
{
if (request.isauthenticated == true)
{
string[] roles;
// 將用戶角色信息存入到cookie
if ((request.cookies["portalroles"] == null) || (request.cookies["portalroles"].value == ""))
{
//當cookies中沒有時,從數據庫中讀取
usersdb user = new usersdb();
roles = user.getroles(user.identity.name);
// 以字符串的形式存儲用戶角色信息用";"分隔,一個用戶的多個角色
string rolestr = "";
foreach (string role in roles)
{
rolestr += role;
rolestr += ";";
}
// 創建身份角色驗證的憑據
formsauthenticationticket ticket = new formsauthenticationticket(
1, // version 版本
context.user.identity.name, // user name cookie 名
datetime.now, // issue time 發布日期
datetime.now.addhours(1), // expires every hour 過期日期
false, // don't persist cookie 持久性(false)
rolestr // roles 用戶定義的數據初始化(";"分隔的角色字符串)
);
// 加密憑證
string cookiestr = formsauthentication.encrypt(ticket);
// 將存有用戶角色信息的字符串存入cookie
response.cookies["portalroles"].value = cookiestr;
response.cookies["portalroles"].path = "/";
response.cookies["portalroles"].expires = datetime.now.addminutes(1);
}
else
{
//當cookies中沒有時,從cookies中讀取
formsauthenticationticket ticket = formsauthentication.decrypt(context.request.cookies["portalroles"].value);
arraylist userroles = new arraylist();
foreach (string role in ticket.userdata.split( new char[] {';'} ))
{
userroles.add(role);
}
roles = (string[]) userroles.toarray(typeof(string));
}
// 從 genericidentity 和角色名稱數組(genericidentity 表示的用戶屬于該數組)初始化 genericprincipal 類的新實例。
context.user = new genericprincipal(context.user.identity, roles);
}
}
5、desktopdefault.aspx中的判斷是否可訪問該頁的代碼
// 當前用戶的角色不在當前活動標簽的可訪問角色中時,重定向到訪問錯誤頁
if (portalsecurity.isinroles(portalsettings.activetab.authorizedroles) == false)
{
response.redirect("~/admin/accessdenied.aspx");
}
6、用戶是否可編輯用戶模塊的代碼
public static bool haseditpermissions(int moduleid)
{
string accessroles;
string editroles;
// 獲取站點的設置信息
siteconfiguration sitesettings = (siteconfiguration) httpcontext.current.items["sitesettings"];
// 在設置信息中找到指定模塊的行(xml中的用戶模塊表module)
siteconfiguration.modulerow modulerow = sitesettings.module.findbymoduleid(moduleid);
//可編輯指定模塊的角色信息
editroles = modulerow.editroles;
//可訪問模塊所屬標簽的角色信息
accessroles = modulerow.tabrow.accessroles;
//既有模塊的編輯權,又有模塊所屬標簽的訪問權的才可修改指定模塊
if(portalsecurity.isinroles(accessroles) == false || portalsecurity.isinroles(editroles) == false)
return false;
else
return true;
}
(先列出一部分,等我全部整理好后再提供整站程序的下載)
更多相關內容:點擊這里>>