Asp.Net基于forms的验证机制,记录一下...

最近在看asp.net forum,对其中的验证机制看得模模糊糊,看完构建安全的 ASP.NET 应用程序中的表单身份验证部分,思路就很清晰了,稍做了点记录,以便查阅:

构建基于forms的验证机制过程如下:
1,设置IIS为可匿名访问和asp.net web.config中设置为form验证
2,检索数据存储验证用户,并检索角色(如果不是基于角色可不用)
3,使用FormsAuthenticationTicket创建一个Cookie并回发到客户端,并存储
  角色到票中,如:
  FormsAuthentication.SetAuthCookie(Username,true | false)
  cookies保存时间:
  HttpContext.Current.Response.Cookies[FormsAuthentication.FormsCookieName].Expires=DateTime.Now.AddDays(1)

  如果需要存储角色,采用:
 FormsAuthenticationTicket authTicket = new
 FormsAuthenticationTicket(
            1, // version
            txtUserName.Text, // user name
            DateTime.Now, // creation
            DateTime.Now.AddMinutes(20),// Expiration
            false, // Persistent
            roles ); // User data
  roles是一个角色字符串数组
  string encryptedTicket = FormsAuthentication.Encrypt(authTicket); //加密

  存入Cookie
  HttpCookie authCookie =
  new HttpCookie(FormsAuthentication.FormsCookieName,
  encryptedTicket);

  Response.Cookies.Add(authCookie);

4,在Application_AuthenticateRequest事件中处理程序中(Global.asax)中,使用
  票创建IPrincipal对象并存在HttpContext.User中
  代码:
  HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
  FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);//解密
  string[] roles = authTicket.UserData.Split(new char[]{';'});//根据存入时的格式分解,;或|....
  Context.User = new GenericPrincipal(Context.User.Identity, Roles);//存在HttpContext.User中

5,需要对某些页面进行角色控制,有两种方法:
 5.1,web.config中加
    <location path="EditPost.aspx">
 <system.web>
  <authorization>
                        <allow roles="RoleName" />
   <deny users="?" />
  </authorization>
 </system.web>
    </location>
 5.2,把只能是某种角色访问的文件放在同一目录下,在此目录下添加一个web.config
   <configuration>
     <system.web>
 <authorization>
           <allow roles="RoleName" />
    <deny users="*" />
 </authorization>
     </system.web>
   </configuration>
  说明:子目录的web.config设置优先于父目录的web.config设置


这里有一篇更全面的总结

posted @ 2004-06-29 11:55 kwklover 阅读(15538) 评论(23) 编辑 收藏

 回复 引用   
#1楼2004-09-25 17:29 | sinitek[未注册用户]
十分感谢。我也在看这个,恰好也是对身份验证没搞明白。
看了你文章 收获很大。 谢谢

 回复 引用   
#2楼2005-01-19 14:52 | checkboxlist
checkboxlist
本人在global.asax中,用了如下代码,


protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
HttpApplication App = (HttpApplication) sender;
HttpContext Ctx = App.Context ; //获取本次Http请求相关的HttpContext对象
if (Ctx.Request.IsAuthenticated == true) //验证过的用户才进行role的处理
{
FormsIdentity Id = (FormsIdentity)Ctx.User.Identity ;
FormsAuthenticationTicket Ticket =Id.Ticket ; //取得身份验证票
string[] Roles = Ticket.UserData.Split (',') ; //将身份验证票中的role数据转成字符串数组
Ctx.User = new GenericPrincipal (Id, Roles) ; //将原有的Identity加上角色信息新建一个GenericPrincipal表示当前用户,这样当前用户就拥有了role信息
}

}




在login.aspx中


用了如下代码 



string strUser = User.Text; //读取用户名
string strPwd = Password.Text; //读取密码

string strRoles = "0admin"; //获取role字符串
FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket (1,strUser,DateTime.Now,DateTime.Now.AddMinutes(30), false,strRoles,"/"); //建立身份验证票对象
string HashTicket = FormsAuthentication.Encrypt (Ticket) ; //加密序列化验证票为字符串
HttpCookie UserCookie = new HttpCookie (FormsAuthentication.FormsCookieName, HashTicket) ; //生成Cookie
Context.Response.Cookies.Add (UserCookie) ; //输出Cookie
FormsAuthentication.RedirectFromLoginPage(User.Text,AbidingCookie.Checked);



但始终没有实现基于角色的验证,能帮我看一下吗?
多谢!

 回复 引用   
#4楼2005-02-26 22:14 | kwklover
@老鹰来自都江堰:
这样实现后,还需要对具体的页面进行控制
1,可以在web.config里配置:
配置某个页面需要那些角色才可以访问
<location path="WebForm1.aspx">
<system.web>
<authorization>
<allow roles="xxx,xxx" />
<deny users="*" />
</authorization>
</system.web>
</location>
如果想控制整个目录需要那些角色可以访问,请看文章第5
2,可以在具体页面的Page_Load事件里加上
if( HttpContext.Current.User.IsInRole(rolename) )
{
//具体处理,....
}
这样虽然可以实现要求,但通常会在实体上封装好使用,具体你可以看.text asp.netforums这些优秀项目的实现

以上的回复希望对你有用

 回复 引用   
#5楼2005-03-06 04:06 | netproxy
Request.IsAuthenticated 并不代表login in,一定要记住这点.
 回复 引用   
#6楼2005-04-04 23:07 | fdasf
good

 回复 引用   
#7楼2005-04-22 22:29 | Garfield
怎么样在客户端读取,存储的用户信息,如用户名和密码等 ??

期待您的帮助 ^_^

 回复 引用   
#8楼2005-04-24 06:22 | kwklover
@Garfield
文种的方法是会把用户的标识(UserID OR Username),Roles存储在客户端的Cookies中,所以从原理上说,你可以通过分析cookies来获得部分用户信息

但是无法获取所有用户信息,因为这些信息根本没有存储在客户端,同时存储在客户端的信息都是加密过的。这是应用安全的需要

所以”怎么样在客户端读取,存储的用户信息,如用户名和密码等 ?? “

似乎不可能哦 ~~~

 回复 引用   
#9楼2005-07-30 11:19 | 老鹰[未注册用户]
当然可以实现,asp.net 提供了对Cookies的加密,也提供了一个函数对Cookies进行解密。
在页面中导入System.Web.Security,
在需要进行解密的地方加入如下代码:
FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(Context.Request.Cookies[FormsAuthentication.FormsCookieName].Value);
要取出用户名,密码只需要非常简单的方法就可以实现:
具体代码如下:
string UserName =ticket.Name.ToString();
string Password=ticket.UserData.ToString();

 回复 引用   
#10楼2005-07-30 11:21 | 老鹰[未注册用户]
[FormsAuthentication.FormsCookieName].Value
就是你的Cookies名称,只要将它更改为你所使用的Cookies即可。
相信这对你有用。

 回复 引用   
#11楼2005-08-11 10:26 | jackymi[未注册用户]
我用asp 该怎么读取用上边的方法生成的cookies信息?

郁闷........

 回复 引用   
#12楼2005-11-23 13:45 | 一休[未注册用户]
为什么这样生成的Cookie无法在客户端找到呢
 回复 引用   
#13楼2006-01-11 21:48 | rocky2008[未注册用户]
在創建票的時候,角色可以從數據庫裡獲得
 回复 引用   
#14楼2006-07-07 08:50 | zzk526[未注册用户]
我用了

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

为什么角色不是admin的用户还可以打开admincreateadmin.aspx页面?

 回复 引用   
#15楼2006-09-20 01:55 | asp[未注册用户]
好像还得加一条 deny users="*" 来拒绝其它的用户
 回复 引用 查看   
#16楼2006-10-19 16:35 | 壮志      
好文章
 回复 引用   
#17楼2006-12-22 15:17 | 车载影音[未注册用户]
好文.