[.NET 基于角色安全性验证] 之二:ASP.NET Forms 身份验证流程分析

Asp.net中基于Forms验证的角色验证授权 Asp.net中基于Forms验证的角色验证授权Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活。Forms 验证方式对基于用户的验证授权提供了很好的支持,可以通过一个登录页面验证用户的身份,将此用户的身份发回到客户端的Cookie,之后此用户再访问这个web应用就会连同这个身份Cooki 阅读详情
MSDN 中提及 FormsAuthenticationModule 在 Forms 身份验证中起到了关键作用,那么这背后究竟隐藏了什么?本分将简要分析 Forms 身份验证流程,以便让大家更加清楚地了解并使用它。

FormsAuthenticationModule 是一个 Http Module,Forms 身份验证通过 FormsAuthenticationModule 参与 ASP.NET 页的生命周期。它在网站应用启动时被初始化,并拦截访问请求,我们继续看看它的细节。
public void Init(HttpApplication app)
{
   // 绑定 HttpApplication 的两个事件,以此来拦截系统的访问请求。
   app.AuthenticateRequest += new EventHandler(this.OnEnter);
   app.EndRequest += new EventHandler(this.OnLeave);
}

private void OnEnter(object source, EventArgs eventArgs)
{
   if (!FormsAuthenticationModule._fAuthChecked || FormsAuthenticationModule._fAuthRequired)
   {
     HttpApplication application1 = (HttpApplication)source;
     HttpContext context1 = application1.Context;

     // 读取 Forms 认证的配置信息
     AuthenticationSection section1 = RuntimeConfig.GetAppConfig().Authentication;
     section1.ValidateAuthenticationMode();

     // 确认 Forms 验证模式
     if (!FormsAuthenticationModule._fAuthChecked)
     {
       FormsAuthenticationModule._fAuthRequired = section1.Mode == AuthenticationMode.Forms;
       FormsAuthenticationModule._fAuthChecked = true;
     }

     if (FormsAuthenticationModule._fAuthRequired)
     {
       // 设置缺省参数
       if (!this._fFormsInit)
       {
         FormsAuthentication.Initialize();
         this._FormsName = section1.Forms.Name;
         if (this._FormsName == null)
         {
           this._FormsName = ".ASPXAUTH";
         }
         FormsAuthenticationModule.Trace("Forms name is: " + this._FormsName);
         this._LoginUrl = section1.Forms.LoginUrl;
         if (this._LoginUrl == null)
         {
           this._LoginUrl = "login.aspx";
         }
         this._fFormsInit = true;
       }

       // 调用验证核心方法
       this.OnAuthenticate(new FormsAuthenticationEventArgs(context1));

       CookielessHelperClass class1 = context1.CookielessHelper;
       if (AuthenticationConfig.AccessingLoginPage(context1, this._LoginUrl))
       {
         context1._skipAuthorization = true;
         class1.RedirectWithDetectionIfRequired(null, FormsAuthentication.CookieMode);
       }
       if (!context1.SkipAuthorization)
       {
         context1._skipAuthorization = AssemblyResourceLoader.IsValidWebResourceRequest(context1);
       }
     }
   }
}

private void OnAuthenticate(FormsAuthenticationEventArgs e)
{
   HttpCookie cookie1 = null;
   if (this._eventHandler != null)
   {
     this._eventHandler(this, e);
   }

   // 检查 User 对象,以确认是否已通过验证。
   if ((e.Context.User != null) || (e.User != null))
   {
     // 处理 Global.asax FormsAuthentication_OnAuthenticate 事件参数。
     if (e.Context.User == null)
     {
       e.Context._user = e.User;
     }
   }
   else
   {
     FormsAuthenticationTicket ticket1 = null;
     bool flag1 = false;
     try
     {
       // 从 Cookie 中提取验证票证对象
       ticket1 = FormsAuthenticationModule.ExtractTicketFromCookie(e.Context, this._FormsName, out flag1);
     }
     catch
     {
       ticket1 = null;
     }

     if ((ticket1 != null) && !ticket1.Expired)
     {
       FormsAuthenticationTicket ticket2 = ticket1;

       // 刷新票证信息
       if (FormsAuthentication.SlidingExpiration)
       {
         ticket2 = FormsAuthentication.RenewTicketIfOld(ticket1);
       }

       // 创建主体和标识对象
       e.Context._user = new GenericPrincipal(new FormsIdentity(ticket2), new string[0]);

       if (!flag1 && !ticket2.CookiePath.Equals("/"))
       {
         cookie1 = e.Context.Request.Cookies[this._FormsName];
         if (cookie1 != null)
         {
           cookie1.Path = ticket2.CookiePath;
         }
       }
       if (ticket2 != ticket1)
       {
         if ((flag1 && (ticket2.CookiePath != "/")) && (ticket2.CookiePath.Length > 1))
         {
           ticket2 = new FormsAuthenticationTicket(ticket2.Version, ticket2.Name, ticket2.IssueDate, ticket2.Expiration, ticket2.IsPersistent, ticket2.UserData, "/");
         }

         // 加密新的票证,并写入 Cookie。
         string text1 = FormsAuthentication.Encrypt(ticket2);
         if (flag1)
         {
           e.Context.CookielessHelper.SetCookieValue('F', text1);
           e.Context.Response.Redirect(e.Context.Request.PathWithQueryString);
         }
         else
         {
           if (cookie1 != null)
           {
             cookie1 = e.Context.Request.Cookies[this._FormsName];
           }
           if (cookie1 == null)
           {
             cookie1 = new HttpCookie(this._FormsName, text1);
             cookie1.Path = ticket2.CookiePath;
           }
           if (ticket2.IsPersistent)
           {
             cookie1.Expires = ticket2.Expiration;
           }
           cookie1.Value = text1;
           cookie1.Secure = FormsAuthentication.RequireSSL;
           cookie1.HttpOnly = true;
           if (FormsAuthentication.CookieDomain != null)
           {
             cookie1.Domain = FormsAuthentication.CookieDomain;
           }
           e.Context.Response.Cookies.Add(cookie1);
         }
       }
     }
   }
}

private void OnLeave(object source, EventArgs eventArgs)
{
   // 调整 URL
   if (FormsAuthenticationModule._fAuthChecked && FormsAuthenticationModule._fAuthRequired)
   {
     HttpApplication application1 = (HttpApplication)source;
     HttpContext context1 = application1.Context;
     if (context1.Response.StatusCode == 0x191)
     {
       string text3;
       string text1 = null;
       if (!string.IsNullOrEmpty(this._LoginUrl))
       {
         text1 = AuthenticationConfig.GetCompleteLoginUrl(context1, this._LoginUrl);
       }
       if ((text1 == null) || (text1.Length <= 0))
       {
         throw new HttpException(SR.GetString("Auth_Invalid_Login_Url"));
       }
       CookielessHelperClass class1 = context1.CookielessHelper;
       string text2 = context1.Request.PathWithQueryString;
       if (text1.IndexOf('?') >= 0)
       {
         text1 = FormsAuthentication.RemoveQueryStringVariableFromUrl(text1, "ReturnUrl");
         text3 = text1 + "&ReturnUrl=" + HttpUtility.UrlEncode(text2, context1.Request.ContentEncoding);
       }
       else
       {
         text3 = text1 + "?ReturnUrl=" + HttpUtility.UrlEncode(text2, context1.Request.ContentEncoding);
       }
       int num1 = text2.IndexOf('?');
       if ((num1 >= 0) && (num1 < (text2.Length - 1)))
       {
         text2 = FormsAuthentication.RemoveQueryStringVariableFromUrl(text2, "ReturnUrl");
       }
       num1 = text2.IndexOf('?');
       if ((num1 >= 0) && (num1 < (text2.Length - 1)))
       {
         text3 = text3 + "&" + text2.Substring(num1 + 1);
       }
       class1.SetCookieValue('F', null);
       class1.RedirectWithDetectionIfRequired(text3, FormsAuthentication.CookieMode);
       context1.Response.Redirect(text3, false);
     }
   }
}

通过对 FormsAuthenticationModule 代码的分析,我们基本可以确定 ASP.NET Forms 身份验证流程。

1. 拦截系统访问,检查身份验证状态。
2. 如未通过验证,则跳转到指定的 loginUrl 接受用户身份数据验证。
3. 如已通过验证,则从 Cookie 中提取身份验证票证对象。
4. 创建用户标识和主体对象,其中标识对象包含了票证引用。
5. 更新票证过期时间,重新写入 Cookie。
6. 调整URL参数,重定向页面。

在整个验证流程中,我们可以看到几个验证的核心类型。包括:

FormsAuthenticationTicket :身份验证票证,保存用户名、过期时间、自定义数据等信息。经 FormsAuthentication.Encrypt 方法加密成字符串后保存到 Cookie 或者 URL 参数中。

GenericPrincipal :用户主体对象。HttpContext.User 就是该类型,用来保存用户身份数据,诸如:FormsIdentity、FormsAuthenticationTicket 等。

FormsIdentity:用户标识对象,可通过 HttpContext.Current.User.Identity 访问。其 Ticket 属性保存了用户身份验证票据引用。

HttpContext:ASP.NET 为每个用户创建的上下文对象,用来保存该用户的相关信息,诸如 Session、GenericPrincipal 等。

FormsAuthentication:ASP.NET Forms 身份验证的核心类之一,其静态属性可访问 Forms Web.config 配置,相关方法用来操作身份验证数据。

 

第 1 篇:对象池模式 (Object Pool) —— 裸机下的动态内存革命 摘要:嵌入式开发中频繁malloc/free会导致内存碎片和性能问题。对象池模式通过预分配固定大小内存块和位图管理,实现O(1)时间复杂度的内存分配/释放。相比malloc,对象池具有无碎片、确定性执行时间、更低内存开销等优势,尤其适合实时系统。文章详细解析了基于位图的对象池实现原理,包括核心数据结构、高性能索引算法和关键API设计,并对比了空间/时间开销,最后讨论了零拷贝队列、调试水印等进阶用法。该模式能显著提升嵌入式系统的内存使用效率和稳定性。 阅读详情

相关推荐

CRaxsRat v7.6 安装与使用教程(附工具下载)

摘要:本文介绍远程管理工具CRaxsRat v7.6的合法应用与基本操作,强调仅限授权环境使用。该工具支持多客户端管理、TLS加密及文件/进程控制等功能,适用于内网维护与安全测试。安装需Windows 10/11系统及.NET 4.8,步骤包括解压运行、配置监听端口及生成客户端。文中提醒防火墙设置与杀软误报问题,并重申禁止非法用途,建议在虚拟机或隔离环境学习使用。

lzj781210的博客 3791

细说ASP.NET身份认证

细说ASP.NET身份认证 阅读目录 开始 ASP.NET身份认证基础 ASP.NET身份认证过程 如何实现登录与注销 保护受限制的页面 登录页不能正常显示的问题 认识Forms身份认证 理解Forms身份认证 实现自定义的身份认证标识 在多台服务器之间使用Forms身份认证 在客户端程序中访问受限页面 用户登录是个很常见的业务需求,在ASP.NE...

weixin_30270889的博客 437

Android Qcom Display学习(十一)

该系列文章总目录链接与各部分简介:本章主要是基于MIPI Payload传输接口的学习,包括Generic和DCS的接口不同。底层都是基于去封装的,下面第一部分调用原生接口,第二部分分析高通是如何进行读写操作的。

Android驱动开发 3182

ASP.Net 2.0窗体身份验证机制详解(FormsAuthentication)

本篇文章介绍了在ASP.Net 2.0如何做窗体身份验证,并且讲解了IIS和ASP.Net2.0窗体身份验证机制是如何结合在一起的。我们还会详细讲解一下2.0中关于窗体身份验证的一个类:FormsAuthenticationModule。 l         综述当某一个用户使用用户名成功登陆网站时,FormsAuthentication(窗体身份验证机制,下面统一使用英文术语) 将会

电子商务 asp.net ajax 1492

Paypal开发者中心获取“ClientId”和“ClientSecret”参数

正式环境设置 1、登录到 paypal开发者中心 网址:https://developer.paypal.com/developer/ 点击右上角登录按钮登录 2、左侧栏 - 我的应用程序和凭证 - 点击“创建新应用” 新注册的paypal账号,需要进行邮箱验证,验证通过后,需要等待一段时间(或重新登录),才会出现相关设置项位置 验证邮箱通过后,点击创建新应用 3、按提示填写,保存创建应用 4、点击刚创建的应用进入应用详情页 5、应用详情页获得网站开发人员所需要的“ClientId”和“Client

龚清林的博客 1万+

手把手教你用VMware虚拟机搭建PCAN开发环境:从Ubuntu安装到CAN通讯实战

本文详细指导如何在VMware虚拟机中搭建PCAN开发环境,涵盖从Ubuntu系统安装、VMware精细配置、PCAN-USB设备直通,到Linux驱动编译、can-utils工具集使用及完整CAN通讯测试的全过程。通过实战步骤与故障排查技巧,帮助开发者快速构建稳定高效的CAN总线开发与测试沙盒,特别适合车载诊断与嵌入式通讯应用。

weixin_29216353的博客 225

ASP.NET底层封装HttpModule实例---FormsAuthentication类的分析

HttpModule是用来注册HttpApplication事件的,实现IHttpModule接口的托管代码模块可以访问该请求管道的所有事件。那么对于我们最常用的ASP.NET Forms身份验证模块是如何底层封装处理的呢?今天过了一遍ASP.NET生命周期,以前的时候喜欢做各种应用,小程序等,渐渐地就觉得真没意思,因为只要你懂点基本的语法,会用相关的库亦或是框架就行,如果出错就是些许的...

anfeng4628的博客 245

LabVIEW与MySQL实时数据存储:传感器采集与数据库同步实践

本文详细介绍了如何将LabVIEW与MySQL结合,实现传感器数据的实时采集与高效存储。通过设计合理的数据库表结构、配置LabVIEW数据库连接工具包,并编写核心的采集与存储VI,构建了稳定可靠的数据链路。文章重点分享了批量插入、连接管理、时间同步等关键优化技巧与避坑指南,帮助工程师应对工业监控、环境监测等场景下的实时数据同步挑战。

weixin_29281915的博客 262

FormsAuthentication 简单使用

网站分为前台后后台管理页面,一般前台部设置用户访问权限,任何用户都可访问,但后台必须是注册用户才能登陆。 【IIS 验证机制】 Asp.net验证分为两步。首先,IIS验证当前用户访问网站所使用的windows帐号是否有权限。如果IIS访问被配置为anonymous,则任何用户都能访问页面。 然后,在IIS验证完毕后,ASP.net开始执行自身的验证。验证模式可以在web.c...

weixin_30364325的博客 164

Microsemi Libero系列教程(一)——Libero开发环境介绍、下载、安装与注册

前言 相比与Xilinx和Altera在国内的市场,Microsemi的FPGA在国内应用很少很少,网上几乎没有详细的教程,刚开始使用时,遇到了各种问题,自己也走了不少弯路。本系列教程以Libero V11.8.2.4,SmartFusion系列A2F200M3F FPGA芯片为例,将详细介绍Libero SoC软件的基本使用,及使用过程中遇到一些问题的解决方法。 Libero 简介 关于Lib...

whik1194的博客 3万+

R语言中的summarise函数和mutate函数用于计算分组占比。下面是关于这两个函数的详细介绍以及相应的源代码示例:

R语言中的summarise函数和mutate函数用于计算分组占比。

CodeByte的博客 1183

基于FormsAuthentication的用户、角色身份认证

一般情况下,在我们做访问权限管理的时候,会把用户的正确登录后的基本信息保存在Session中,以后用户每次请求页面或接口数据的时候,拿到 Session中存储的用户基本信息,查看比较他有没有登录和能否访问当前页面。 Session的原理,也就是在服务器端生成一个SessionID对应了存储的用户数据,而SessionID存储在Cookie中,客户端以后每次请求都会带...

weixin_30522183的博客 707

基于双目视觉的行车中障碍距离检测方法研究与目标跟踪

本文将介绍基于Python语言的双目视觉技术,以及如何使用该技术检测行车中的障碍物并跟踪目标。双目视觉利用两个摄像头模拟人眼的立体视觉,通过对两个摄像头所捕捉的图像进行比较和分析,可以得到物体的深度信息。首先,我们需要安装Python的OpenCV库,该库提供了丰富的图像处理和计算机视觉功能。接下来,我们进入一个循环中,不断读取左右图像,并将其转换为灰度图像。在视差图上,您可以实现目标检测和跟踪算法来识别和跟踪行车中的障碍物。请注意,上述代码只是一个简单示例,您可以根据具体需求和算法进行修改和扩展。

ZgnObjectivec的博客 277

[转][.NET 基于角色安全性验证] 之二:ASP.NET Forms 身份验证流程分析

MSDN 中提及 FormsAuthenticationModule 在 Forms 身份验证中起到了关键作用,那么这背后究竟隐藏了什么?本分将简要分析 Forms 身份验证流程,以便让大家更加清楚地了解并使用它。 FormsAuthenticationModule 是一个 Http Module,Forms 身份验证通过 FormsAuthenticationModule 参与 ASP.N...

weixin_34413357的博客 110

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

如何通过 Active Directory 使用 Forms 身份验证

如何通过 Active Directory 使用 Forms 身份验证发布日期: 10/28/2004 | 更新日期: 10/28/2004浏览全部“安全性指南”主题Microsoft Corporation目标本模块用于: •创建使用 Forms 身份验证来针对 Active Directory 对用户进行身份验证的 Web 应

江湖·郎中·路 3168

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

[.NET 基于角色安全性验证] 之三:ASP.NET Forms 身份验证

 在开发过程中,我们需要做的事情包括:1. 在 web.config 中设置 Forms 身份验证相关参数。2. 创建登录页。登录页中的操作包括:1. 验证用户名和密码是否正确。2. 创建身份验证票证对象。3. 将身份验证票证对象加密成字符串,写入 Cookies。4. 重定向到原始请求 URL。1. 简单演示web.config                                

CafeeJ的专栏 505

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

ASP.NET 用户和角色管理 附加代码详解

文章目录1. 身份验证和授权1.1. 身份验证1.2. 授权2. 登录控件2.1. CreateUserWizard控件2.2. Login控件2.3. LoginName控件2.4. LoginStatus控件2.5. LoginView控件2.6. changePassword控件2.7. PasswordRecovery控件 1. 身份验证和授权 1.1. 身份验证 1.2. 授权 2. 登...

白水的博客 4425

Asp.net身份验证Membership与授权——身份验证配置(1)

用户的身份验证和授权是从用户处获取用户凭据如用户名和密码,并通过某些授权机构验证那些凭据的过程。如果这些凭据有效,则视为通过身份验证上,在身份得到验证后,并确定该身份是否可以访问特定资源。几乎所有的web站点和基于浏览器的系统中都会使用的功能,例如:新建、修改、删除用户和角色,为用户分配角色,管理角色中的用户等等。身份验证是确认用户身份的过程,就是解决是谁的问题,在用户通过身份验证后,可以确定该用

了空 2828

[.NET 基于角色安全性验证] 之三:ASP.NET Forms 身份验证(转)

在开发过程中,我们需要做的事情包括:1. 在 web.config 中设置 Forms 身份验证相关参数。2. 创建登录页。登录页中的操作包括:1. 验证用户名和密码是否正确。2. 创建身份验证票证对象。3. 将身份验证票证对象加密成字符串,写入 Cookies。4. 重定向到原始请求 URL。1. 简单演示web.config<?xml version="1.0"?>&lt...

diaodai2269的博客 157

asp.net Forms表单验证 使用经验及验证流程分析

      最近,要做一个登陆的页面,就想到了安全性方面的问题。记得曾经在邵志东老师讲的关于asp.net安全性方面的课程中,提到asp.net提供了4个身份验证程序:1.表单身份验证;2.Windows身份验证;3.Passport身份验证;4.默认身份验证。尤其讲了表单身份验证,想想,正好自己以前也不曾使用过这个验证方式,那就拿来练练手吧。      表单验证,可以根据用户和角色来限制用户

wyf1022的专栏 920
上一篇: [.NET 基于角色安全性验证] 之一:ASP.NET Forms 基础
下一篇: [.NET 基于角色安全性验证] 之三:ASP.NET Forms 身份验证
yangfcf
博客等级 码龄19年 10粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值