1.使用Forms验证存储用户自定义信息

Forms验证在内部的机制为把用户数据加密后保存在一个基于cookie的票据FormsAuthenticationTicket中,因为是经过特殊加密的,所以应该来说是比较安全的。而.net除了用这个票据存放自己的信息外,还留了一个地给用户自由支配,这就是现在要说的UserData。

UserData可以用来存储string类型的信息,并且也享受Forms验证提供的加密保护,当我们需要这些信息时,也可以通过简单的get方法得到,兼顾了安全性和易用性,用来保存一些必须的敏感信息还是很有用的。

下面来看怎么使用UserData,然后会给出一个实际使用的例子。

//创建一个新的票据,将客户ip记入ticket的userdata
FormsAuthenticationTicket ticket=new FormsAuthenticationTicket(
1,userName.Text,DateTime.Now,DateTime.Now.AddMinutes(30),
false,Request.UserHostAddress);
//将票据加密
string authTicket=FormsAuthentication.Encrypt(ticket);
//将加密后的票据保存为cookie
HttpCookie coo=new HttpCookie(FormsAuthentication.FormsCookieName,authTicket);
//使用加入了userdata的新cookie
Response.Cookies.Add(coo);
下面是FormsAuthenticationTicket构造函数的重载之一的方法签名
public FormsAuthenticationTicket(
int version,
string name,
DateTime issueDate,
DateTime expiration,
bool isPersistent,
string userData
);
参数
version
版本号。
name
与身份验证票关联的用户名。
issueDate
Cookie 的发出时间。
expiration
Cookie 的到期日期。
isPersistent
如果 Cookie 是持久的,为 true;否则为 false。
userData
将存储在 Cookie 中的用户定义数据

使用userdata也很简单,FormsIdentity的Ticket属性就提供了对当前票据的访问,获得票据后就可以用UserData属性访问保存的信息,当然是经过解密的。
((System.Web.Security.FormsIdentity)this.Context.User.Identity).Ticket.UserData

下面是一个具体的应用。

由于Forms验证是通过cookie来进行的,它需要传递一个票据来进行工作。虽然票据是加密的,里面的内容不可见,但这并不能阻止别人用一个假冒的身份使用票据(就像我们可以拿别人的钥匙去开别人的锁),比较常见的就是不同ip的用户在不安全通道截获了这个票据,然后使用它进行一些安全范围外的活动。

解决这个问题的办法之一就是使用SSL来传递信息。

但是如果不能使用SSL呢?我们可以判断ip和票据是否匹配,如果发出请求的ip是初次产生票据的ip,则没有问题,否则就销毁这个票据。

为此,我们需要在一开始处理登录时将用户的ip保存起来,这样就可以在以后的请求中随时验证后继请求的ip是否和初始ip相同。保存这个敏感ip的最佳场所当然是UserData啦,而验证的时机则是在AuthenticateRequest事件发生时,即Global.aspx.cs中定义的处理此事件的Application_AuthenticateRequest方法中。

上面的示例实际上已经是把用户ip保存到了UserData中,下面是验证的过程。

if(this.Request.IsAuthenticated)
{
if(((System.Web.Security.FormsIdentity)this.Context.User.Identity).Ticket.UserData !=this.Request.UserHostAddress)
{
System.Security.Principal.GenericIdentity gi=new System.Security.Principal.GenericIdentity("","");
string[] rolesi={};
System.Security.Principal.GenericPrincipal gpi=new System.Security.Principal.GenericPrincipal(gi,rolesi);
this.Context.User=gpi;
}
}

通过给GenericPrincipal空的GenericIdentity和roles使票据失效,这样将强迫用户重新登录。为了测试这个方法,可以先把条件改为相等,看效果如何 :)

这个方法也有不足之处,具体为:

1.使用同一代理的用户将拥有同一个ip,这样就不能防范此类假冒攻击了

2.如果用户使用动态ip,则可能造成正常用户被我们强行销毁票据。不过总的来说,这个办法还是比较可行的。

FormsAuthenticationTicket基于forms的验证

构建基于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, // 版本号。
  txtUserName.Text, // 与身份验证票关联的用户名。
  DateTime.Now, // Cookie 的发出时间。
  DateTime.Now.AddMinutes(20),// Cookie 的到期日期。
  false, // 如果 Cookie 是持久的,为 true;否则为 false。
  roles ); // 将存储在 Cookie 中的用户定义数据。
  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中
 判断某个角色验证
 HttpContext.Current.User.IsInRole(roles)
 具体实现
 Web.config文件
 加入节点,name为COOKIE名称,loginUrl为没有通过验证跳转的地址
 <system.web>
  <authentication mode="Forms">
  <forms name="Hstear"
 loginUrl="login.aspx" protection="All" path="/" timeout="40"/>
  </authentication>
 </system.web>
 设置目录访问 path为目录名,roles为票据中的角色名
 发现网上的都说要单独一个WEB.CONFIG文件放在目录中,但实际在根目录中设置即可,单个文件也一样
 <location path="Admin">
  <system.web>
  <authorization>
  <allow roles="admin"/>
  <deny users="*"/>
  </authorization>
  </system.web>
 </location>
 Global.asax文件
 Application_AuthenticateRequest事件中加入
  protected void Application_AuthenticateRequest(Object sender, EventArgs e)   {  string cookieName = FormsAuthentication.FormsCookieName;  HttpCookie authCookie = Context.Request.Cookies[cookieName];  FormsAuthenticationTicket authTicket = null;  try  {   authTicket = FormsAuthentication.Decrypt(authCookie.Value);  }  catch(Exception ex)  {   return;  }    string[] roles = authTicket.UserData.Split(new char[]{','});//如果存取多个角色,我们把它分解    FormsIdentity id = new FormsIdentity( authTicket );    GenericPrincipal principal = new GenericPrincipal(id, roles);  Context.User =principal;//存到HttpContext.User中     }  
 原理,将用户角色信息保存在票据中,通过Global.asax,WEB.CONFIG中的设置,判断角色的权限

原文 http://www.cnblogs.com/zxjyuan/archive/2009/08/21/1551196.html

【转载】FormsAuthenticationTicket 对象的更多相关文章

  1. 转载C# 对象转Json序列化

    转载原地址:  http://www.cnblogs.com/plokmju/p/ObjectByJson.html JSON Json(JavaScript Object Notation) 是一种 ...

  2. [转载]C#对象序列化与反序列化

    文章写的实在是太好了,忍不住转来: http://www.cnblogs.com/LiZhiW/p/3622365.html#_Toc8478 1.对象序列化的介绍 (1).NET支持对象序列化的几种 ...

  3. 转载--js对象无法当成参数传递

    今天我碰到了这个问题一头雾水,明明记得对象是可以传参的啊.我使用了一款基于bootstrap的表格插件DataTables,想把行信息直接传给操作函数,方便编辑(此行信息是一个对象,按道理可以的啊), ...

  4. (转载)JSON对象使用变量作为键名

    转载链接:https://blog.csdn.net/lihefei_coder/article/details/82499520 //第一种方式 var key = 'name'; var json ...

  5. 经典FormsAuthenticationTicket 分析

    Asp.net中基于Forms验证的角色验证授权 Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多, ...

  6. FormsAuthenticationTicket学习笔记

    FormsAuthenticationTicket ticket = , ), true, string.Format("{0}:{1}", "username" ...

  7. ASP.NET Forms身份认证详解

    ASP.NET身份认证基础 在开始今天的内容之前,我想有二个最基础的问题首先要明确: 1. 如何判断当前请求是一个已登录用户发起的? 2. 如何获取当前登录用户的登录名? 在标准的ASP.NET身份认 ...

  8. 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  9. ASP.NET 身份认证

    ASP.NET 身份认证相关 原理 ASP.NET中身份认证分为两个阶段:认证与授权 1. 认证:识别当前请求的用户是不是一个可识别(登录)用户.AuthenticateRequest 2. 授权:是 ...

随机推荐

  1. springMVC注解用法:@modelattribute的用法

    在Spring MVC里,@ModelAttribute通常使用在Controller方法的参数注解中,用于解释model entity,但同时,也可以放在方法注解里. 如果把@ModelAttrib ...

  2. Android中实现整个视图切换的左右滑动效果

    Android中提供了一个Gallary,可以实现图片或者文本的左右滑动效果. 如何让整个视图都能实现左右滑动,达到类似于Gallary的效果呢?可以直接用一个开源的ViewFlow来实现.   项目 ...

  3. 10.static_extern

    另一个文件声明 #include <iostream> using namespace std; ; void show() { cout << " << ...

  4. Spark 概念学习系列之Spark存储管理机制

    Spark存储管理机制 概要 01 存储管理概述 02 RDD持久化 03 Shuffle数据存储 04 广播变量与累加器 01 存储管理概述 思考: RDD,我们可以直接使用而无须关心它的实现细节, ...

  5. [python]bug和debug

    bug:代码中存在的语法或者逻辑问题 debug:自查和解决代码中的问题 (coding五分钟,debug两小时) 一.出现bug原因的四大类型 1.粗心 1)错误案例 上面这个错误就是因为 if语句 ...

  6. HTML中input标签maxlength属性的妙处

    HTML中的input标签可是很常用的. HTML本身也非常简单,就是若干标签,每个标签有若干属性. 我在学习HTML的过程中,也没有太过重视. 今年,在写前端表单验证的时候,发现maxlength这 ...

  7. FarPoint.Win.Spread 常规操作

    FarPoint.Win.Spread.FpSpread fSpread = new FarPoint.Win.Spread.FpSpread();             //设置 行数.列数    ...

  8. 微服务实战(二):使用API Gateway - DockOne.io

    原文:微服务实战(二):使用API Gateway - DockOne.io [编者的话]本系列的第一篇介绍了微服务架构模式.它讨论了采用微服务的优点和缺点,除了一些复杂的微服务,这种模式还是复杂应用 ...

  9. startActivityForResult()方法具体解释

    我们都知道.要开启一个Activity能够在上下文环境中调用startActivity()方法. 可是假设想从开启的Activity中获取某些数据,就能够使用startActivityForResul ...

  10. 6.5 Android硬件访问服务使用反射

    1.前面的例子中App为了能够范问ILedService接口,把classes.jar导入到应用程序中,但是我们不想把classes编进apk包里面去,这样导致我们的apk程序会很大(解压缩apk会发 ...