asp.net中使用基于角色role的Forms验证

http://www.cnblogs.com/yao/archive/2006/06/24/434783.html

asp.net中使用基于角色role的Forms验证,大致经过几下四步:
1.配置系统web.config

system.web> 
<authentication mode="Forms" > 
 <forms name=".yaoCookies" loginUrl="/duan/Manage/login.aspx" protection="All"
  timeout="20" path="/" />
 </authentication>
</system.web>

其中<authentication mode= "forms"> 表示本应用程序采用Forms验证方式。
1).
<forms>标签中的name表示指定要用于身份验证的 HTTP Cookie。默认情况下,name 的值是
.ASPXAUTH。采用此种方式验证用户后,以此用户的信息建立一个FormsAuthenticationTicket类型的身份验证票,再加密序列
化为一个字符串,最后将这个字符串写到客户端的name指定名字的Cookie中.一旦这个Cookie写到客户端后,此用户再次访问这个web应用时会
将连同Cookie一起发送到服务端,服务端将会知道此用户是已经验证过的.

2). <forms>标签中的loginUrl指定如果没有找到任何有效的身份验证 Cookie,为登录将请求重定向到的
URL。默认值为
default.aspx。loginUrl指定的页面就是用来验证用户身份的,一般此页面提供用户输入用户名和密码,用户提交后由程序来根据自己的需要
来验证用户的合法性(大多情况是将用户输入信息同数据库中的用户表进行比较),如果验证用户有效,则生成同此用户对应的身份验证票,写到客户端的
Cookie,最后将浏览器重定向到用户初试请求的页面.一般是用FormsAuthentication.RedirectFromLoginPage
方法来完成生成身份验证票,写回客户端,浏览器重定向等一系列的动作.

public static void RedirectFromLoginPage( string userName, bool createPersistentCookie, string strCookiePath );

其中:
userName: 就是此用户的标示,用来标志此用户的唯一标示,不一定要映射到用户账户名称.
createPersistentCookie: 标示是否发出持久的 Cookie。

不是持久Cookie,Cookie的有效期Expiration属性有当前时间加上web.config中timeout的时间,每次请求页面时,在验
证身份过程中,会判断是否过了有效期的一半,要是的话更新一次cookie的有效期;若是持久cookie,Expiration属性无意义,这时身份验
证票的有效期有cookie的Expires决定,RedirectFromLoginPage方法给Expires属性设定的是50年有效期。
strCookiePath:

标示将生成的Cookie的写到客户端的路径,身份验证票中保存这个路径是在刷新身份验证票Cookie时使用(这也是生成Cookie的Path),若
没有strCookiePath 参数,则使用web.config中 path属性的设置。

这里可以看到,此方法参数只有三个,而身份验证票的属性有七个,不足的四个参数是这么来的:
IssueDate:Cookie发出时间由当前时间得出,
Expiration:过期时间由当前时间和<forms>标签中的timeout参数算出。此参数对非持久性cookie有意义。
UserData:这个属性可以用应用程序写入一些用户定义的数据,此方法没有用到这个属性,只是简单的将此属性置为空字符串,请注意此属性,在后面我们将要使用到这个属性。
Version: 版本号由系统自动提供。

RedirectFromLoginPage方法生成生成身份验证票后,会调用FormsAuthentication.Encrypt 方法,将身份验证票加密为字符串,这个字符串将会是以.ASPXAUTH为名字的一个Cookie的值。
这个Cookie的其它属性的生成:
Domain,Path属性为确省值,Expires视createPersistentCookie参数而定,若是持久cookie,Expires设为50年以后过期;若是非持久cookie,Expires属性不设置。
生成身份验证Cookie后,将此Cookie加入到Response.Cookies中,等待发送到客户端。
最后RedirectFromLoginPage方法调用FormsAuthentication.GetRedirectUrl 方法获取到用户原先请求的页面,重定向到这个页面。

3). <forms>标签中的timeout和path,是提供了身份验证票写入到Cookie过期时间和默认路径。

以上就是基于Forms身份验证的过程,它完成了对用户身份的确认。

2.在受保护的文件夹如Manage下创建一web.config文件,内容如

configuration>
  <!--指定对整个Manage目录的访问权限-->
  <system.web>
     <authorization>
           <!--多个角色用,分隔-->
           <allow roles="admin,user"/>
           <deny users="*" />
       </authorization>
  </system.web>

<!--也可控制某个页的权限

<location path="AnnounceList.aspx">
     <system.web>
        <authorization>
           <allow roles="admin"/>
           <deny users="*" />
        </authorization>
     </system.web>
  </location>

<location path="ConfigInfo.aspx">
     <system.web>
        <authorization>
           <allow roles="users"/>
           <deny users="*" />
        </authorization>
     </system.web>
  </location>

-->
</configuration>

注:此配置内容也可以加入到系统的web.config文件中,注意加入位置:

system.web>

<location path="Manage/AnnounceList.aspx">
     <system.web>
      <authorization>
       <allow roles="admin"/>
       <deny users="*" />
      </authorization>
     </system.web>
    </location>

</configuration>

<allow>标签表示允许访问,其中的属性
1). users:一个逗号分隔的用户名列表,这些用户名已被授予对资源的访问权限。问号 (?) 允许匿名用户;星号 (*) 允许所有用户。
2). roles:一个逗号分隔的角色列表,这些角色已被授予对资源的访问权限。
3). verbs:一个逗号分隔的 HTTP 传输方法列表,这些 HTTP 传输方法已被授予对资源的访问权限。注册到 ASP.NET 的谓词为 GET、HEAD、POST 和 DEBUG。

<deny>标签表示不允许访问。其中的属性同上面的。

在运行时,授权模块迭代通过 <allow> 和 <deny>
标记,直到它找到适合特定用户的第一个访问规则。然后,它根据找到的第一项访问规则是 <allow> 还是 <deny>
规则来允许或拒绝对 URL 资源的访问。Machine.config 文件中的默认身份验证规则是 <allow
users="*"/>,因此除非另行配置,否则在默认情况下会允许访问。

那么这些user 和roles又是如何得到的呢?下面看一下授权的详细过程:

1).
一旦一个用户访问这个网站,就行登录确认了身份,身份验证票的cookie也写到了客户端。之后,这个用户再次申请这个web的页面,身份验证票的
cookie就会发送到服务端。在服务端,asp.net为每一个http请求都分配一个HttpApplication对象来处理这个请求,在
HttpApplication.AuthenticateRequest事件后,安全模块已建立用户标识,就是此用户的身份在web端已经建立起来,这
个身份完全是由客户端发送回来的身份验证票的cookie建立的。
2). 用户身份在HttpContext.User
属性中,在页面中可以通过Page.Context
来获取同这个页面相关的HttpContext对象。对于Forms验证,HttpContext.User属性是一个GenericPrincipal
类型的对象,GenericPrincipal只有一个公开的属性Identity,有个私有的m_role属性,是string[]类型,存放此用户是
属于哪些role的数组,还有一个公开的方法IsInRole(string role),来判断此用户是否属于某个角色。
由于身份验证票的cookie中根本没有提供role这个属性,就是说Forms身份验证票没有提供此用户的role信息,所以,对于Forms验证,在服务端得到的GenericPrincipal 用户对象的m_role属性永远是空的。
3).
GenericPrincipal. Identity
属性是一个FormsIdentity类型的对象,这个对象有个Name属性,就是此用户的标示,访问授权就是将此属性做为user来进行授权验证的。
FormsIdentity还有一个属性,就是Ticket属性,此属性是身份验证票FormsAuthenticationTicket类型,就是之前
服务器写到客户端的身份验证票。
服务器在获取到身份验证票FormsAuthenticationTicket对象后,查看这个身份验证票是不是
非持久的身份验证,是的话要根据web.config中timeout属性设置的有效期来更新这个身份验证票的cookie(为避免危及性能,在经过了超
过一半的指定时间后更新该 Cookie。这可能导致精确性上的损失。持久性 Cookie 不超时。)
4).
在HttpApplication.ResolveRequestCache事件之前,asp.net开始取得用户请求的页面,建立
HttpHandler控制点。这就意味着,在HttpApplication.ResolveRequestCache事件要对用户访问权限就行验证,
看此用户或角色是否有权限访问这个页面,之后在这个请求的生命周期内再改变此用户的身份或角色就没有意义了。

以上是Forms验证的全过
程,可以看出,这个Forms验证是基于用户的,没有为角色的验证提供直接支持。身份验证票FormsAuthenticationTicket
中的Name属性是用户标示,其实还有一个属性UserData,这个属性可以由应用程序来写入自定义的一些数据,我们可以利用这个字段来存放role的
信息,从而达到基于角色验证的目的。

3.登录页

void Button1_Click(object sender, System.EventArgs e)
{
            //实体类AdminUserVO对应AdminUser用户表。
            AdminUserVO adminUserVO = new AdminUserVO();

adminUserVO.Uname = UserName.Text.Trim();
            adminUserVO.Upwd = UserPwd.Text.Trim();
            adminUserVO.LastIP = HttpContext.Current.Request.UserHostAddress;
            adminUserVO.LastTime = DateTime.Now;

bool flag = (new LoginDAO()).Chk(adminUserVO);

if (flag)
            {
                //非角色验证时可以用这句:
                //System.Web.Security.FormsAuthentication.SetAuthCookie(UserName.Text.Trim(),false);

//创建角色验证信息,把role信息写入到UserData中
                SetLoginCookie(adminUserVO,adminUserVO.Roles.ToLower());

HttpContext.Current.Response.Redirect("Main.aspx");
            }
            else
            {
                HttpContext.Current.Response.Write("登录失败");
            }
}

static void SetLoginCookie(AdminUserVO u, string roles)
  {
   //建立身份验证票对象
   FormsAuthenticationTicket ticket = new FormsAuthenticationTicket (1,u.Uname, DateTime.Now, DateTime.Now.AddMinutes(30), false,roles,"/");
   //加密序列化验证票为字符串
   string hashTicket = FormsAuthentication.Encrypt (ticket) ;
   HttpCookie userCookie = new HttpCookie(FormsAuthentication.FormsCookieName, hashTicket);
   HttpContext.Current.Response.Cookies.Add(userCookie);
  }

FormsAuthenticationTicket参数说明:
FormsAuthenticationTicket(
int version, //设为1,版本号由系统自动提供
string name, //用户标示,获取与身份验证 Cookie 关联的用户名
DateTime issueDate, //Cookie 的发出时间, 设置为 DateTime.Now
DateTime expiration, //获取 Cookie 过期的日期/时间
bool isPersistent, //是否持久性(根据需要设置,若是设置为持久性,在发出cookie时,cookie的Expires设置一定要设置),如果已发出持久的 Cookie,则返回 true。否则,身份验证 Cookie 将限制在浏览器生命周期范围内。
string userData, //获取存储在 Cookie 中的应用程序定义字符串,这里用上面准备好的用逗号分割的role字符串
string cookiePath // 返回发出 Cookie 的路径。注意,窗体的路径设置为"/",这要同发出cookie的路径一致,因为刷新cookie要用这个路径。由于窗体区分大小写,这是为了防止站点中的 URL 的大小写不一致而采取的一种保护措施。
);

4.Global.asax.cs

void Application_AuthenticateRequest(Object sender, EventArgs e)
  {
   HttpApplication app = (HttpApplication) sender;  
   HttpContext ctx = app.Context ; //获取本次Http请求的HttpContext对象  
   if (ctx.User != null)
   {
    if (ctx.Request.IsAuthenticated == true) //验证过的一般用户才能进行角色验证  
    {  
     System.Web.Security.FormsIdentity fi = (System.Web.Security.FormsIdentity)ctx.User.Identity ;  
     System.Web.Security.FormsAuthenticationTicket ticket = fi.Ticket ; //取得身份验证票  
     string userData = ticket.UserData;//从UserData中恢复role信息
     string[] roles = userData.Split (‘,‘) ; //将角色数据转成字符串数组,得到相关的角色信息  
     ctx.User = new System.Security.Principal.GenericPrincipal (fi, roles) ; //这样当前用户就拥有角色信息了
    } 
   }
  }

注:如果使用HttpModule的话,此处代码应该加入在AuthenticateRequest事件中。

时间: 2024-08-07 00:07:00

asp.net中使用基于角色role的Forms验证的相关文章

在Postgresql中添加新角色(Role)

Postgresql安装完成之后,默认会创建名为postgres的用户.角色(Role)和数据库(Database).而使用你自己原有的用户运行psql时会提示错误. [email protected]:~$ psql psql: FATAL: role "bob" does not exist 如果想要使用自己的用户"bob"来运行psql,就需要在Postgresql中添加名为"bob"的角色(Role). [email protected]

在Tomcat中采用基于表单的安全验证

1.概述   (1)基于表单的验证 基于From的安全认证可以通过TomcatServer对Form表单中所提供的数据进行验证,基于表单的验证使系统开发者可以自定义用户的登陆页面和报错页面.这种验证方法与基本HTTP的验证方法的唯一区别就在于它可以根据用户的要求制定登陆和出错页面. 通过拦截并检查用户的请求,检查用户是否在应用系统中已经创建好login session.如果没有,则将用户转向到认证服务的登录页面.但在Tomcat中的基于表单的验证凭证不被保护并以纯文本发送.   (2)在Tomc

ASP.NET中获取登录用户ID 用户身份验证(转载)

如果VS2005及VS2008中使用菜单[网站]-[ASP.NET配置]进入使用网站管理工具(WAT)的表单验证(Forms验证)方式来建立网站数据库,默认数据库名为ASPNETDB.MDF.系统将会自动建立一套系统数据表(VS2008中为11个这样的数据表),利用这个系统数据表可以快捷地进行创建新用户.角色.用户登录.修改用户口令等开发. 在后续开发过程中,需要反复使用用户ID.判断用户是否为登录用户或者是否为某一角色,这些常用操作如下: 1.获取当前登录用户ID Membership.Get

Yii中 RBAC(基于角色的访问控制权限)表结构原理分析

这里有几个概念很重要,我简单用大白话说一下; 权限:就是指用户是否可以执行哪些操作. 如:小张可以发帖.回帖.浏览,小红只能回帖.浏览 角色:就是上面说的一组操作的集合. 如:高级会员有发帖.回帖.删贴.浏览的权限,普通会员只有回帖.浏览的权限.比如小张是高级会员,那么他就可以执行发帖.回帖.删贴.浏览.而小红是普通会员,所以它就只能回帖.浏览. 另外角色还可以继承,中级会员除了普通会员的回帖.浏览功能外,还可以发帖.也就是说在普通会员的基础上又增加了一个发帖的权限. 在Yii2.0中 yii\

ASP.NET Core 2.1中基于角色的授权

ASP.NET Core 2.1中基于角色的授权 授权是来描述用户能够做什么的过程.例如,只允许管理员用户可以在电脑上进行软件的安装以及卸载.而非管理员用户只能使用软件而不能进行软件的安装以及卸载.它是独立的而又与验证配合使用,需要身份验证机制.对于应用程序来说,首先需要进行身份验证,然后进行进行授权. 作者:依乐祝 原文链接:https://www.cnblogs.com/yilezhu/p/9508267.html Identity是一个会员资格系统,它允许我们将登录功能添加到我们的应用程序

使用Lync 2013 基于角色的权限控制:RBAC 给用户分配指定的操作权限

使用场景: 在大型的Lync统一沟通系统的日常运维中,我们需要为不同角色的管理员分配不同的Lync管理权限,在Lync Server 2013上面就使用了基于角色的权限控制:RBAC ,它里面分了多种权限角色,包括 CsAdministrator,CsUserAdministrator,CsVoiceAdministrator,CsServerAdministrator,CsViewOnlyAdministrator,CsHelpDesk等等,不同的角色有不同的Lync管理权限, 例如,当我们只

C 实现基于角色的权限系统

本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1068 实例使用C# 实现基于角色的权限菜单管理系统, 管理员可以添加用户,删除用户, 添加分组,删除分组, 添加角色,删除角色,为角色关联权限等功能, 管理员用户自定义各个操作员的权限菜单标题 项目对应的实例代码可以通过右侧[下载实例]按钮获取 开发工具: VS2012 数据库: SQLServer [项目包含内容](见下图): [实例

ASP.NET Identity 身份验证和基于角色的授权

ASP.NET Identity 身份验证和基于角色的授权 阅读目录 探索身份验证与授权 使用ASP.NET Identity 身份验证 使用角色进行授权 初始化数据,Seeding 数据库 小结 在前一篇文章中,我介绍了ASP.NET Identity 基本API的运用并创建了若干用户账号.那么在本篇文章中,我将继续ASP.NET Identity 之旅,向您展示如何运用ASP.NET Identity 进行身份验证(Authentication)以及联合ASP.NET MVC 基于角色的授权

ASP.net MVC 基于角色的权限控制系统的实现

一.引言 我们都知道ASP.net mvc权限控制都是实现AuthorizeAttribute类的OnAuthorization方法. 下面是最常见的实现方式: public class CustomAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (!filterContext.RequestContext