Forms身份认证
大家都知道Http是无状态的协议,所以访问一个url,你并不能知道用户在之前是否已经登陆过。但是许多业务上的逻辑又离不开user的信息,这个时候就可以借助身份认证来记录当前user的登录状态。这其中Forms身份认证是最常见的身份认证。
这篇博客讲的内容就是结合一个最普通的MVC工程来讲解下Forms身份认证是怎么实现记录用户登录状态的。并说下怎么自定义一个身份认证。
打开Visual Studio 2013,新建Asp.net web mvc application,选择Internet Application
建好之后,按F5就能看到新建的网站。
修改Index,cshtml:
@if (Request.IsAuthenticated)
{
<text>用户已登录:</text>
@Context.User.Identity.Name
}
else
{
<text>用户未登录</text>
}
运行之后,你能看到:

继续修改Index.cshtml
@if (Request.IsAuthenticated)
{
<text>用户已登录:</text>
@Context.User.Identity.Name
}
else
{
<text>用户未登录</text>
<form method="post" action="@Request.RawUrl">
<input type="text" name="userName" />
<input type="submit" value="Submit" />
</form>
}
在对应的HomeController里加上对应的方法:
[HttpPost]
public ActionResult Index(string id)
{
string userName = Request.Params["userName"];
FormsAuthentication.SetAuthCookie(userName, true);
return Index();
}
按F5运行之后,在输入框内填上user name,运行之后的结果:

注意上述的结果都是在web.config里开启Forms认证的基础上
<authentication mode="Forms">
</authentication>
Forms身份认证的核心类是FormsAuthenticationModule
它是一个http module,实现了接口IHttpModule,这个接口的主要方法:
Init(HttpApplication Context)
看FomrsAuthenticationModule的实现
public void Init(HttpApplication app)
{
if (!_fAuthChecked)
{
_fAuthRequired = AuthenticationConfig.Mode == AuthenticationMode.Forms;
_fAuthChecked = true;
}
if (_fAuthRequired)
{
FormsAuthentication.Initialize();
app.AuthenticateRequest += new EventHandler(this.OnEnter);
app.EndRequest += new EventHandler(this.OnLeave);
}
}
解释下代码,这个方法首先判断是否开启了Forms 认证,如果是Forms认证,就注册了两个HttpApplication管道事件AuthenticateRequest和EndRequest,继续看下
注册的AuthenticateRequest事件
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
this.OnAuthenticate(new FormsAuthenticationEventArgs(context));
找到了最核心的方法OnAuthenticate
由于此方法比较长,笔者只摘录出最核心的几句话
FormsAuthenticationTicket tOld = ExtractTicketFromCookie(e.Context, FormsAuthentication.FormsCookieName, out cookielessTicket);
e.Context.SetPrincipalNoDemand(new GenericPrincipal(new FormsIdentity(ticket), new string[]));
可以看出最核心的方法是Forms module从http context中的Cookie中解析出FormsAuthenticationTicket对象,然后new出来FormsIdentity,最后传给HttpContext
module一般都是注册Application管道事件,在事件里实现自己的核心处理,比如MVC,也是Module,实现自己的UrlRoutingModule,注册ResolveRequestCache事件
Authorization可以控制user对网站的访问权限,比如哪种user可以访问哪种资源
在上述的工程web.config里加上
<authentication mode="Forms">
<forms loginUrl="~/Home/Index"/>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
deny users="?"代表只有登录用户才可以访问网站
于此对应的还有allow users="*" 允许任何用户可以访问
此类功能是UrlAuthorizationModule 实现,在此不在赘述,实现方式和FormsAuthenticationModule方式大同小异。
在某些业务功能里,需要cookie记住的功能不仅仅是user name,比如remember me功能,这个时候就可以用自定义身份认证来实现。
至于实现方式,既然已经知道Forms身份认证怎么实现,完全可以比葫芦画瓢实现自己需要的认证
下面写一个简单的实例
首先仿照FormsAuthenticationModule,注册AuthenticateRequest事件
protected void Application_AuthenticateRequest()
{
HttpContext context = HttpContext.Current;
if (!context.Request.RawUrl.Equals("/"))
{
HttpCookie cookie = context.Request.Cookies["CustomCookie"];
string[] strs = cookie.Value.Split('x');
bool rememberMe = Convert.ToInt32(strs[]) == ? true : false;
HttpContext.Current.User = new CustomPrincipal(new CustomIdentity(strs[], rememberMe));
}
}
标注:
context.Request.RawUrl.Equals("/") 此句是简单的将Index.cshtml作为登录页面,实际应用中当然需要修改下。
其中CustomPrincipal和CustomIdentity类的代码如下
public class CustomPrincipal : IPrincipal
{
private IIdentity identity; public CustomPrincipal(IIdentity identity)
{
this.identity = identity;
} public IIdentity Identity
{
get { return identity; }
} public bool IsInRole(string role)
{
throw new NotImplementedException();
}
} public class CustomIdentity : IIdentity
{ private string name;
private bool rememberMe; public CustomIdentity(string name, bool rememberMe)
{
this.name = name;
this.rememberMe = rememberMe;
} public string AuthenticationType
{
get { return string.Empty; }
} public bool IsAuthenticated
{
get { return true; }
} public string Name
{
get { return name; }
}
}
Index.cshtml继续作为登录页面,对应的登录方法:
[HttpPost]
public ActionResult Index(string id)
{
string userName = Request.Params["userName"];
HttpCookie cookie = new HttpCookie("CustomCookie");
cookie.Value = userName + "x" + .ToString();
cookie.Expires = DateTime.Now.AddHours();
System.Web.HttpContext.Current.Response.SetCookie(cookie);
return RedirectToAction("About");
}
About.cshtml作为判断是否登录的页面
@if (Request.IsAuthenticated)
{
<text>用户已登录:</text>
@Context.User.Identity.Name
}
else
{
<text>用户未登录</text>
}
最后运行结果:

到此,整篇博客已结束,许多地方说的还是比较简单抽象,望理解。
Forms身份认证的更多相关文章
- 细说ASP.NET Forms身份认证
阅读目录 开始 ASP.NET身份认证基础 ASP.NET身份认证过程 如何实现登录与注销 保护受限制的页面 登录页不能正常显示的问题 认识Forms身份认证 理解Forms身份认证 实现自定义的身份 ...
- 简单的ASP.NET Forms身份认证
读了几篇牛人的此方面的文章,自己也动手做了一下,就想有必要总结一下.当然我的文章质量自然不能与人家相比,只是写给从没有接触过这个知识点的朋友. 网站的身份认证我以前只知道session,偶然发现一些牛 ...
- IE11下Forms身份认证无法保存Cookie的问题
ASP.NET中使用Forms身份认证常见的做法如下: 1. 网站根目录下的Web.config添加authentication节点 <authentication mode="For ...
- [转]IE11下Forms身份认证无法保存Cookie的问题
本文转自:http://www.cnblogs.com/jaxu/p/3698377.html ASP.NET中使用Forms身份认证常见的做法如下: 1. 网站根目录下的Web.config添加au ...
- IE11下ASP.NET Forms身份认证无法保存Cookie的问题
IE11下ASP.NET Forms身份认证无法保存Cookie的问题 折腾了三四天,今天才找到资料,解决了. 以下会转贴,还没来得及深究,先放着,有空再学习下. ASP.NET中使用Forms身份认 ...
- 关于Asp.Net Forms身份认证
Asp.Net管道式的构建个我们提供了通过IHttpMoudle来订阅管线事件来达到干预HTTP请求的目的,Asp.Net的身份认证正是通过此种方式来对请求来执行身份认证的,这篇文章仅仅谈论Forms ...
- 权限管理学习 一、ASP.NET Forms身份认证
说明:本文示例使用的VS2017和MVC5. 系统无论大小.牛逼或屌丝,一般都离不开注册.登录.那么接下来我们就来分析下用户身份认证. 简单实现登录.注销 以前在学习.net的时候不知道什么Forms ...
- 【转】权限管理学习 一、ASP.NET Forms身份认证
[转]权限管理学习 一.ASP.NET Forms身份认证 说明:本文示例使用的VS2017和MVC5. 系统无论大小.牛逼或屌丝,一般都离不开注册.登录.那么接下来我们就来分析下用户身份认证. 简单 ...
- ASP.NET Forms身份认证详解
ASP.NET身份认证基础 在开始今天的内容之前,我想有二个最基础的问题首先要明确: 1. 如何判断当前请求是一个已登录用户发起的? 2. 如何获取当前登录用户的登录名? 在标准的ASP.NET身份认 ...
随机推荐
- CodeForces 589A Email Aliases (匹配,水题)
题意:给定于所有的邮箱,都是由login@domain这样的形式构成,而且字符都是不区分大小写的. 我们有一种特殊类型的邮箱——@bmail.com, 这种邮箱除了不区分大小写外—— 1,'@'之前的 ...
- Spring Data JPA教程, 第四部分: JPA Criteria Queries(未翻译)
The third part of my Spring Data JPA tutorialdescribed how you can create custom queries by using qu ...
- Unity3D之Mecanim动画系统学习笔记(五):Animator Controller
简介 Animator Controller在Unity中是作为一种单独的配置文件存在的文件类型,其后缀为controller,Animator Controller包含了以下几种功能: 可以对多个动 ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- status pending状态
开发采用ssh,注解的方式,事物也application.xml配置了,但是在业务层没有使用@Transactional造成浏览器一直处于status pending状态,为什么没有使用@Transa ...
- android ipc通信机制之之三,进程通讯方式。
IPC通讯方式的优缺点: IPC通讯方式的对比 名称 优点 缺点 适用场景 Bundle 简单易用 只能传输Bundle支持的数据类型 四大组件的进程通信 文件共享 简单易用 不适合高并发场景,并无法 ...
- 【转】Android 实现ListView的滑动删除效果
http://www.cnblogs.com/weixiao870428/p/3524055.html http://download.csdn.net/download/love_javc_you/ ...
- eclipse中异常的快捷键
选中你要try的代码,alt+shift+z 就会弹出一个菜单,里面有个try 选项
- Cocos2d-x中由sprite来驱动Box2D的body运动(用来制作平台游戏中多变的机关)
好久都没写文章了,就来一篇吧.这种方法是在制作<胖鸟大冒险>时用到的.<胖鸟大冒险>中使用Box2D来进行物理模拟和碰撞检測,因此对每一个机关须要创建一个b2body.然后&l ...
- 【转】教你Ruby快速入门
转自:http://developer.51cto.com/art/200703/41243.htm 介绍 这是一个短小的Ruby入门,完全读完只需20分钟.这里假设读者已经安装了Ruby,如果你没有 ...