Your Ad Here
首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 网站建设 > ASP > 解读ASP.NET Portal Starter Kit(4)——角色身份认证篇
【标  题】:解读ASP.NET Portal Starter Kit(4)——角色身份认证篇
【关键字】:ASP.NET,Portal,Starter,Kit
【来  源】:http://blog.csdn.net/webplat/archive/2006/08/17/1076985.aspx

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

Your Ad Here
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" + ">";
    }

}


4Global.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;
}

ASP.NET Portal Starter 源码深入剖析[简]:【上一篇】
解读ASP.NET Portal Starter Kit(3)——代码文件篇:【下一篇】
【相关文章】
  • ASP.NET Portal Starter 源码深入剖析[简]
  • 1000本ASP/ASP.NET程序设计电子书专题下载
  • 代码编写规范说明书(c#.net与asp.net)
  • 《SharePoint Portal Server 2003 深入指南》出版预告
  • 遭遇RootKit.Vanti.kn、Trojan.PSW.JHOnline.eqo、Trojan.PSW.LMir.ktn等
  • 微软推出Best Practice Analyzer for ASP.Net组态扫瞄工具
  • asp.net输出纯xml格式数据
  • ASP.NET2.0里的web.config配置接口API(转)
  • ASP.net中数据分页是由自己管理好还是由控件管理好?
  • 在Asp.net中调用异步方法--使用信号量
  • 【随机文章】
  • JSP与EJB(1)
  • 帧中继技术
  • 创业者和VC,互联网时期的大忽悠们——我懒,整理晚了
  • Java中的语句、分支和路径覆盖测试
  • 在Suse10下尝试dogtail(一个python的GUI测试工具)的笔记(二)
  • Linux命令——pkg-config
  • 让FireFox记住yahoo mail 和 msn passport 的用户名和密码
  • 用 RPM 打包软件(第 2 部分)zt
  • 封装对文章的各种操作(插入数据库、从数据库取出等等)
  • How To Set Up A Load-Balanced MySQL Cluster - Part 3
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.