FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(, "username", DateTime.Now, DateTime.Now.AddDays(),
true, string.Format("{0}:{1}", "username", "password"), FormsAuthentication.FormsCookiePath);
//这边的 string.Format("{0}:{1}", "username", "password"),也可以改为任何值,如密码或IP
string ticString = FormsAuthentication.Encrypt(ticket);
//将加密后的票据保存为cookie
HttpCookie coo = new HttpCookie(FormsAuthentication.FormsCookieName, ticString);
//这里的IsPersistent不会自己判断,需要手工判断,但FormsAuthenticationTicket的expiration的值是有过期性的,无论cookie的Expires设置多久,只要expiration到期,即使cookie存在用户验证也将失败
if (ticket.IsPersistent)
{
coo.Expires = ticket.Expiration;
}
//使用加入了userdata的新cookie
Response.Cookies.Add(coo);
//FormsAuthentication.SetAuthCookie("username", true);//这种是快速写法,用了这种写法就可以不用自己建ticket票据,也无法使用UserData等参数了 //FormsAuthentication.SignOut//用来清除这个Cookie标记//FormsAuthentication.RedirectFromLoginPage(userID, createPersistentCookie); // <authentication mode="Forms">
// <forms name=".MyCookie" loginUrl="Login.aspx" protection="All" timeout="60"/>
// </authentication>

总结:

1.FormsAuthentication一共有两种生成并记录票具的方法:

  一种是自己new FormsAuthenticationTicket,然后自己保存到Cookie中,ticket的 IsPersistent属性仅起到标识的作用,并不会去修改Cookies的到期时间,需要人工自己判断后设置cookies的到期时间(if (ticket.IsPersistent){coo.Expires = ticket.Expiration; })。

  另一种是使用FormsAuthentication.SetAuthCookie("username",IsPersistent: false);来快捷生成ticket,这种方法系统会自动新建一个cookies来保存ticket,并根据IsPersistent是否为true, 以及webconfig中的timeout来确定cookies的到期时间。

2.如果使用第一种方法,无论自己把cookies的时间设置为多久,只要ticket.Expiration到期了,及时cookies还存在,用户验证依然会失败。

3.UserData是个好东西,可以用来存储IP地址,用于判断访问者是否是恶意截取cookies。

FormsAuthenticationTicket对象

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中的设置,判断角色的权限

FormsAuthenticationTicket学习笔记的更多相关文章

  1. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  2. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

  3. PHP-会员登录与注册例子解析-学习笔记

    1.开始 最近开始学习李炎恢老师的<PHP第二季度视频>中的“章节5:使用OOP注册会员”,做一个学习笔记,通过绘制基本页面流程和UML类图,来对加深理解. 2.基本页面流程 3.通过UM ...

  4. 2014年暑假c#学习笔记目录

    2014年暑假c#学习笔记 一.C#编程基础 1. c#编程基础之枚举 2. c#编程基础之函数可变参数 3. c#编程基础之字符串基础 4. c#编程基础之字符串函数 5.c#编程基础之ref.ou ...

  5. JAVA GUI编程学习笔记目录

    2014年暑假JAVA GUI编程学习笔记目录 1.JAVA之GUI编程概述 2.JAVA之GUI编程布局 3.JAVA之GUI编程Frame窗口 4.JAVA之GUI编程事件监听机制 5.JAVA之 ...

  6. seaJs学习笔记2 – seaJs组建库的使用

    原文地址:seaJs学习笔记2 – seaJs组建库的使用 我觉得学习新东西并不是会使用它就够了的,会使用仅仅代表你看懂了,理解了,二不代表你深入了,彻悟了它的精髓. 所以不断的学习将是源源不断. 最 ...

  7. CSS学习笔记

    CSS学习笔记 2016年12月15日整理 CSS基础 Chapter1 在console输入escape("宋体") ENTER 就会出现unicode编码 显示"%u ...

  8. HTML学习笔记

    HTML学习笔记 2016年12月15日整理 Chapter1 URL(scheme://host.domain:port/path/filename) scheme: 定义因特网服务的类型,常见的为 ...

  9. DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记

    今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...

随机推荐

  1. C# 多线程参数的使用

    一个参数: Thread.Start方法可以带一个参数: public static void Main() { Thread t = new Thread(new ParameterizedThre ...

  2. MSSQL手札一 MSSQL的游标

    和oracle的不同,MSSQL中没有隐式游标的说法,也没有%type和%rowtype这样根据数据库字段实时更新变量含义的关键字,MSSQL的游标类似于oracle的显示游标,需要自己去手动关闭, ...

  3. HDU 3920Clear All of Them I(状压DP)

    HDU 3920   Clear All of Them I 题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人 ...

  4. How Tomcat Works(十四)

    我们已经知道,在tomcat中有四种类型的servlet容器,分别为Engine.Host.Context 和Wrapper,本文接下来对tomcat中Wrapper接口的标准实现进行说明. 对于每个 ...

  5. A Dream

    A Dream 2013年10月20日,成都,天气阴,铜牌16.离2012年10月14日长春现场赛刚好隔了一年,刚看了下去年写的总结http://blog.csdn.net/cc_again/arti ...

  6. PowerDesigner 表视图修改

    PowerDesigner中Table视图同时显示Code和Name,像下图这样的效果: 实现方法:Tools-Display Preference 转自:http://www.shaoqun.com ...

  7. UI:页面传值、单例模式传值、属性传值、NSUserDefaults 数据持久化

    <单页面传值> 页面传值,从前向后传值,使用属性,在后一个页面定义属性,在前一个页面,用点语法,获得值,在适当的时候传值 页面传值,从后向前面传值,使用协议和代理,在后一个页面指定协议,定 ...

  8. 史上最全APP推广渠道

    群主做App推广的过程中,有过失败也尝过成功的甜头,渐渐地在APP推广尤其是渠道推广中积累了一些实战经验想同大家分享.如果各位有更好的推广建议,欢迎沟通分享哦!   一.应用商店推广   1.应用市场 ...

  9. EXTJS AJAX解析XML数据

    public String getAllAreaInfos() { try { List<Areainfo> list = null; if(areaName!=null&& ...

  10. Owin管道与asp.net管道模型

    ------2016.3.6 更新 文中提到没有Microsoft.Owin.Host.SystemWeb 这个dll 便不会加载Startup.Configuration,因为这个dll 其中有个O ...