Asp.Net 4.0 FormAuthentication 原理
建立一个使用Asp.Net Membership管理登陆登出信息的网站
1. 创建一个Asp.Net Mvc 3 示例网站。
2. 创建自定义的MemberShipProvider,并在Web.CONFIG中配置生效。
a. 创建MyMmbProv
1: public class MyMmbProv : MembershipProvider2: {3:4: ...........5: ///implement ValidateUser just return true, so any user name will be ok6: public override bool ValidateUser(string username, string password)7: {8: return true;9: }10: }b. 配置Web.config的Membership/Providers节点。
1: <;membership defaultProvider="MySqlMembershipProvider">2: <;providers>3: <;clear/>4: <;add name="MySqlMembershipProvider" type="CookieTest.Provider.MyMmbProv" connectionStringName="ApplicationServices"5: enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"6: maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"7: applicationName="/" />;8: </providers>
注意membership节点的defaultProvider 要设置为新增的MembershipProvider节点的名称。
3. 设置网站认证模式为Form
1: <;authentication mode="Forms">
2: <;forms loginUrl="~/Account/LogOn" timeout="20" name="cookie_test" defaultUrl="~/Home/About" slidingExpiration="false" cookieless="UseUri"/>
3: </authentication>
此时Form认证使用Uri来存储cookie信息。
测试UseUri Form认证
登陆后发现页面的url中多了一长串类似加密cookie的内容:http://192.168.4.22/(F(fyt-FBDHvrANVba89TNUrMqn9w_ZgSN9xNEX3C8yIfbRIA-q6IyZhnKFh9mWwLN2kxuFUs0HxlKSTBSp7wPyoqxQhJGsguu1lbwjERZ3kfiHt1w7oD8x9LcGwZNjlY-yzM81YcMVyxbY3G74Yp5YOhGswI5NIg4Ehq3FOu0WbSo5BEkUeDbVFkeflmXZDfD70))/Home/About 而且LogOnPartial中显示出刚才登陆时输入的用户名称
将上述url粘贴到别的浏览器(或者其他同一局域网的机器上)(如上次测试使用chrome,这次使用firefox),发现自动登陆进去了,而且显示出同样的用户名,说明在该URL中至少已经包含了用户名称信息。
也就是说只要能够拿到用户登陆的URL就可以直接登陆该用户的账号!
测试UseCookies Form认证
将cookieless属性改为UseCookies
1: <;authentication mode="Forms">
2: <;forms loginUrl="~/Account/LogOn" timeout="20" name="cookie_test" defaultUrl="~/Home/About" slidingExpiration="false" cookieless="UseCookies"/>
3: </authentication>
用户登陆后每次页面请求都会带上cookie:
从上图中看到登陆数据提交后,返回的Response Headers有一个Set-Cookie的属性,这就是该用户的cookie信息。
登陆后查看其他页面时的页面数据如下图:
可以看到,登陆后每个页面请求的Request Headers 都会加上Cookie(如上图)。
那如果我们通过javascript给未登陆页面增加上述cookie信息结果会是怎样呢?
1: <script type="text/javascript">
1:
2: $(document).ready(function () {
3: $("#setCookie").click(function () {
4: var cookieVal = $("#inputCookie").val();
5: document.cookie = cookieVal;
6: });
7: });
8:
</script>
2: <h2>About</h2>
3: <p>
4: Put content here.
5: <br/>
6: SessionId: @Session.SessionID
7:
8: </p>
9: <div>
10: <input type="text" id="inputCookie" />
11:
12: <br/>
13:
14: <input id="setCookie" value="Set Cookie" type="button"/>
15: </div>
此时页面上显示为已登录状态,不过继续访问其他的页面会有所不同:其中无需认证的页面不会显示登录用户信息;而有认证要求的页面却会显示出登录用户的信息。
再将cookie_test=XXXXXXXXX赋给该页面,然后刷新页面发现已经是登出状态。
由此可见整个Asp.Net 的FormAuthentication都是依赖于cookie或者uri来实现登录的。
在类FormsAuthentication中可以看到:
1: private static HttpCookie GetAuthCookie(string userName, bool createPersistentCookie, string strCookiePath, bool hexEncodedTicket)
2: {
3: FormsAuthentication.Initialize();
4: if (userName == null)
5: userName = string.Empty;
6: if (strCookiePath == null || strCookiePath.Length < 1)
7: strCookiePath = FormsAuthentication.FormsCookiePath;
8: DateTime utcNow = DateTime.UtcNow;
9: DateTime expirationUtc = utcNow.AddMinutes((double) FormsAuthentication._Timeout);
10: FormsAuthenticationTicket ticket = FormsAuthenticationTicket.FromUtc(2, userName, utcNow, expirationUtc, createPersistentCookie, string.Empty, strCookiePath);
11: string str = FormsAuthentication.Encrypt(ticket, hexEncodedTicket);
12: if (str == null || str.Length < 1)
13: throw new HttpException(System.Web.SR.GetString("Unable_to_encrypt_cookie_ticket"));
14: HttpCookie httpCookie = new HttpCookie(FormsAuthentication.FormsCookieName, str);
15: httpCookie.HttpOnly = true;
16: httpCookie.Path = strCookiePath;
17: httpCookie.Secure = FormsAuthentication._RequireSSL;
18: if (FormsAuthentication._CookieDomain != null)
19: httpCookie.Domain = FormsAuthentication._CookieDomain;
20: if (ticket.IsPersistent)
21: httpCookie.Expires = ticket.Expiration;
22: return httpCookie;
23: }
FromsAuthenticationTicket 包含了用户信息、过期时间、是否持久化、cookie路径,并且进过了加密处理。
另外:登陆时勾选记住密码后在..\Windows\Temporary Internet Files\ 文件夹中会多出一个文件
文件的内容如下:
cookie_test
39F80DBA2E9193EF18498E9B65186DAA0A259873DA0EF839990D457F53BBE2270325838A1BF9FF7409E10E8B13C1E7C805B3F2621C22065EEFAB12F953E4523163FD4ACC9F5312F0EC66112A81FDFFF2B5564481526D5B996F13EA42219AE760DD68CEEDD7E40E8BCD3F68D6E1BC0D73EE9D13798BAFB38B6143B334BE70BD31995430B3FCF90DC3A0514DB180682B9E
192.168.1.3/
9728
3254446592
30352998
4140518480
30352995
*
与Request Header 中的Cookie内容比较
cookie_test=39F80DBA2E9193EF18498E9B65186DAA0A259873DA0EF839990D457F53BBE2270325838A1BF9FF7409E10E8B13C1E7C805B3F2621C22065EEFAB12F953E4523163FD4ACC9F5312F0EC66112A81FDFFF2B5564481526D5B996F13EA42219AE760DD68CEEDD7E40E8BCD3F68D6E1BC0D73EE9D13798BAFB38B6143B334BE70BD31995430B3FCF90DC3A0514DB180682B9E
多出了IP地址以及过期时间。
cookie的写入读取都是由CookielessHelperClass来完成的。
本文测试代码
Asp.Net 4.0 FormAuthentication 原理的更多相关文章
- ASP.NET 2.0 异步页面原理浅析 [1]
与 ASP.NET 1.0 相比,ASP.NET 2.0 的各方面改进可以说是非常巨大的.但就其实现层面来说,最大的增强莫过于提供了对异步页面的支持.通过此机制,编写良好的页面可以将数据库.WebSe ...
- ASP.NET 4.0 来了
伴随着VS2010的公开测试,ASP.NET4.0也进入了我们的视线.ASP.NET4.0究竟给我们带来了什么,将在哪些方面提高我们的生产力? 在何时你需要使用ASP.NET4.0开发你的网站程序? ...
- Win10 IIS以及ASP.NET 4.0配置问题日志
问题日志 升级到Win10并安装了VS2015后,原有ASP.NET 4.0项目在本机的IIS部署出现问题. 安装IIS: 在[控制面板.程序.启用或关闭Windows功能.Internet Info ...
- Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器
Asp.Net MVC4.0 官方教程 入门指南之二--添加一个控制器 MVC概念 MVC的含义是 “模型-视图-控制器”.MVC是一个架构良好并且易于测试和易于维护的开发模式.基于MVC模式的应用程 ...
- 【ASP.NET Core】运行原理之启动WebHost
ASP.NET Core运行原理之启动WebHost 本节将分析WebHost.CreateDefaultBuilder(args).UseStartup<Startup>().Build ...
- 【ASP.NET Core】运行原理[3]:认证
本节将分析Authentication 源代码参考.NET Core 2.0.0 HttpAbstractions Security 目录 认证 AddAuthentication IAuthenti ...
- 【ASP.NET Core】运行原理(2):启动WebHost
本系列将分析ASP.NET Core运行原理 [ASP.NET Core]运行原理[1]:创建WebHost [ASP.NET Core]运行原理[2]:启动WebHost [ASP.NET Core ...
- 【ASP.NET Core】运行原理(1):创建WebHost
本系列将分析ASP.NET Core运行原理 [ASP.NET Core]运行原理[1]:创建WebHost [ASP.NET Core]运行原理[2]:启动WebHost [ASP.NET Core ...
- Log4Net异常日志记录在asp.net mvc3.0的应用
前言 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是简单的介绍如何在Visual ...
随机推荐
- 转:面试题:“你能不能谈谈,java GC是在什么时候,对什么东西,做了什么事情?”
转自:http://jeromecen1021.blog.163.com/blog/static/18851527120117274624888/ 面试题目: 地球人都知道,Java有个东西叫垃圾收集 ...
- Linux添加主机路由
Linux添加主机路由:参考:http://zhidao.baidu.com/link?url=50qQ232ZiJqq1iftHvBdPzZh-JlQGi1DZ8wvF-j9dvQYsKiNgc-6 ...
- Map接口
Map实现的包括HashMap 和TreeMap .建议使用HashMap ,效率更高.并且允许使用null值,单是必须保证键的唯一性,TreeMap不允许有空.在添加删除和定位映射关系的时候不如Ha ...
- OpenStreetMap/Google/百度/Bing瓦片地图服务(TMS)
开源与成熟商业的瓦片地图服务(TMS 2 WMTS),都有如下共同的特性,基本成为了标准: (1) 坐标系:WGS84 (2) 投影:墨卡托投影(Marcator,正轴等角圆柱投影) ------ ...
- 用c++写一个简单的计算器程序
// 050305.cpp : 定义控制台应用程序的入口点.// // 050304.cpp : 定义控制台应用程序的入口点.////四则运算#include "stdafx.h" ...
- JS中的split
个人理解spilt函数是javascript中字符串和正则表达式的一个联合应用.功能是根据指定的正则表达式(如果是字符串的话也会转为正则表达式)对字符串进行分割.返回值是一个被分割后的字符串数组. 最 ...
- mysql连接查询,封装mysql函数
连接查询 交叉连接语法: select * | 字段列表 from 表1 cross join 表2 内连接: select *|字段列表 from 左表 inner join 右表 on 左表. ...
- php使用ajax导出CSV或者EXCEl(thinkphp)方法
首先我强烈推荐看到这篇文章的你将导出文件设置为csv格式的文件 实际测试导出csv文件的速度是excel文件的10几倍左右 首先我先介绍csv文件的导出的方法: 如果你单纯是在数据导出界面上通过用户点 ...
- 用Qt Creator 对 leveldb 进行简单的读写
#include <iostream> #include <string> #include <leveldb/db.h> #include <boost/l ...
- AngularJS-chapter2-7-前端路由
Form表单提交会导致页面之间的切换,没法实现单页应用 Ajax请求不会留下History记录(在后台管理系统,没有后台历史记录还可以) ,但在网络型应用或门户型应用(用户没有办法给改页面加标签或分享 ...