分享
 
 
 

解读ASP.NET Portal Starter Kit(4)——角色身份认证篇

王朝asp·作者佚名  2006-01-31
窄屏简体版  字體: |||超大  

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;

}

(先列出一部分,等我全部整理好后再提供整站程序的下载)

更多相关内容:点击这里>>

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有