MVC Controllers和Forms验证
想想下,一组从Forms验证抽象出来的登入/登出Controllers行为特有的ActionResult实现。。
我已经使用ASP.NETMVC重新实现了我的个人网站(projects.nikhilk.net)的一部分。其中之一就是登入/登出功能的实现。当你创建一个新的ASP.NETMVC应用程序,默认的就会包含一个简单的AccountController。这个Controller中包含了登入/登出,并实现了IFormsAuthentication接口。其默认实现基于System.Web.Security.FormsAuthentication APIs(SetAuthCookie and SignOut)。可以仿照给这个接口的实现以便用于United测试。
尽管如此,当我在自己的Controller中实现登入/登出时,我发现一个奇怪现象,行为(actions)直接的访问FormsAuthentication(甚至是通过接口)。我以为行为应该简单地完成用户验证,而后返回一个处理生成响应的匹配的ActionResult,这该实例中就是设置或清除cookie,并重定向Url。为此,我创建了FormsLoginResult和FormsLogoutResult。很明显的他们是成对的出现的,but I thought I'd go ahead and share anyway。
首先,我将显示AccountController中修改过的Login和Logout方法。
[AcceptVerbs(HttpVerbs.Post)] public ActionResult Login(string username, string password, bool rememberMe) {...if (ViewData.ModelState.IsValid) {// Attempt to loginbool loginSuccessful = Provider.ValidateUser(username, password);if (loginSuccessful) {return new FormsLoginResult(username, rememberMe);}else {...}}// If we got this far, something failed, redisplay form...return View(); }public ActionResult Logout() {return new FormsLogoutResult(); }
现在Login和Logout行为不再和authentication是否通过cookie跟踪以及需要重定位到哪里(默认主页、参数关联的url等)相关联。
其次、建立这两个函数的测试单元。我使用Moq实现测试需要的MembershipProvider的模拟,当是不再需要IFormsAuthentication的实现。
[TestClass] public class AccountControllerTest {[TestMethod]public void LoginSuccessful() {string testUserName = "TestUser";string testPassword = "TestPassword";Mock<MembershipProvider> mockMembership = new Mock<MembershipProvider>();mockMembership.Expect<bool>(m => m.ValidateUser(testUserName, testPassword)).Returns(true).AtMostOnce().Verifiable();AccountController controller = new AccountController(mockMembership.Object);ActionResult result = controller.Login(testUserName, testPassword, false);Assert.IsInstanceOfType(result, typeof(FormsLoginResult));FormsLoginResult loginResult = (FormsLoginResult)result;Assert.AreEqual<string>(loginResult.UserName, testUserName);Assert.AreEqual<bool>(loginResult.PersistentCookie, false);}[TestMethod]public void LoginFailure() {string testUserName = "TestUser";string testPassword = "TestPassword";Mock<MembershipProvider> mockMembership = new Mock<MembershipProvider>();mockMembership.Expect<bool>(m => m.ValidateUser(testUserName, testPassword)).Returns(true).AtMostOnce().Verifiable();AccountController controller = new AccountController(mockMembership.Object);ActionResult result = controller.Login(testUserName, "badPassword", false);Assert.IsInstanceOfType(result, typeof(ViewResult));} }
下面是FormsLoginResult 和FormsLogoutResult的实现。这里使用了MVC提供的构建自定义action results可扩展性较好的实现。
public class FormsLoginResult : ActionResult {private string _userName;private string _userData;private bool _persistentCookie;public FormsLoginResult(string userName): this(userName, /* persistentCookie */ false) {}public FormsLoginResult(string userName, bool persistentCookie) {if (String.IsNullOrEmpty(userName)) {throw new ArgumentNullException("userName");}_userName = userName;_persistentCookie = persistentCookie;}public bool PersistentCookie {get { return _persistentCookie; }}public string UserData {get { return _userData; }set { _userData = value; }}public string UserName {get { return _userName; }}public override void ExecuteResult(ControllerContext context) {HttpResponseBase response = context.HttpContext.Response;if (String.IsNullOrEmpty(_userData)) {FormsAuthentication.SetAuthCookie(_userName, _persistentCookie);}else {FormsAuthenticationTicket ticket =new FormsAuthenticationTicket(1, _userName,DateTime.Now, DateTime.Now.AddMinutes(30),_persistentCookie,_userData, FormsAuthentication.FormsCookiePath);string encryptedTicket = FormsAuthentication.Encrypt(ticket);HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName,encryptedTicket);cookie.HttpOnly = true;cookie.Secure = FormsAuthentication.RequireSSL;cookie.Path = FormsAuthentication.FormsCookiePath;if (FormsAuthentication.CookieDomain != null) {cookie.Domain = FormsAuthentication.CookieDomain;}response.Cookies.Add(cookie);}response.Redirect(FormsAuthentication.GetRedirectUrl(_userName, _persistentCookie));} }
令人庆幸的是,FormsLoginResult同样的在FormsAuth cookie内封装了一些自定义用户数据,这些数据可以通过HttpApplication的Authenticate事件获取,并可以使用FormsAuthentication.Decrypt将AuthCookie内数据转换为一个FormsAuthenticationTicket实例,以及从Ticket中获取的用户数据。我在我的网站中使用这个跟踪一些元数据以便于在Requests后重新创建代理实例。
第二个action result FormsLogoutResult非常简单。
public class FormsLogoutResult : ActionResult {private string _url;public FormsLogoutResult(): this(FormsAuthentication.DefaultUrl) {}public FormsLogoutResult(string url) {if (String.IsNullOrEmpty(url)) {throw new ArgumentNullException("url");}_url = url;}public string Url {get { return _url; }}public override void ExecuteResult(ControllerContext context) {FormsAuthentication.SignOut();context.HttpContext.Response.Redirect(_url);} }源:http://www.nikhilk.net/Default.aspx
转载于:https://www.cnblogs.com/Silicon-Fado/archive/2009/03/15/1412198.html
MVC Controllers和Forms验证相关推荐
- ASP.NET MVC 实现统一登录验证
1.先写个主页面 using System; using System.Collections.Generic; using System.Linq; using System.Web; using ...
- 就是这么简单(续)!使用 RestAssuredMockMvc 测试 Spring MVC Controllers(转)
接我前面一篇文章关于RestAssured测试Restful web service的, RestAssured还有一个功能, 使用RestAssuredMockMvc 单元测试你的Spring MV ...
- 使用Spring 3 MVC处理表单验证
本文是有关Spring 3的系列文章的一部分.该系列的早期文章是使用Spring 3 MVC的Hello World和使用Spring 3 MVC的 Handling Forms . 现在让我们更深入 ...
- ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)
ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需要将相应的ValidationAttri ...
- Asp.net中基于Forms验证的角色验证授权[转]
Asp.net的身份验证有有三种,分别是"Windows | Forms | Passport",其中又以Forms验证用的最多,也最灵活. Forms 验证方式对基于用户的验证授 ...
- MVC中的统一验证机制~续
前段时间我发表的关于MVC架构中对验证方式的设计,收到了不少朋友的留言,意思是说过于复杂,复用性不高,当然我的出发点是减少实体部门的代码量. 最近在朋友的建议下,看了另一种验证方式,事实上就是MVC实 ...
- Nancy之Forms验证
授权几乎是所以系统都不可或缺的部分,在Nancy中怎么授权呢?我们这篇博文来说一下Nancy的Forms授权. 首先在NuGet上安装Nancy.Authentication.Forms Nancy的 ...
- ASP.NET MVC 4 (十) 模型验证
模型验证是在模型绑定时检查从HTTP请求接收的数据是否合规以保证数据的有效性,在收到无效数据时给出提示帮助用户纠正错误的数据. 显式模型验证 验证数据最直接的方式就是在action方法中对接收的数据验 ...
- 浅谈ASP.NET Forms验证
ASP.NET Forms验证 用户验证是每一个项目必须的一个模块,由于已经很久没有碰到这一块内容,今天写一个用户验证居然脑子一片空白.于是乎就和一个同事进行了一片讨论,晚上回家决定把讨论的结果给记录 ...
最新文章
- XenServer和VMware vSphere技术比较
- GRE OVER IPSEC
- C++ Primer 5th笔记(chap 19 特殊工具与技术)定位 new 表达式
- 插入,选择,归并,快速排序
- C# WinForm开发系列 - DataGridView
- maven项目概念模型图
- 如何用计算机做出折线图,曲线图怎么做-怎样在电脑上做曲线图电脑上如何做曲线图 – 手机爱问...
- Atitit 软件项目非法模块与功能的管理与 监狱管理的对比 原理与概论attilax总结
- paip.c#.net 多线程调用控件的问题
- c语言实现 网络嗅探程序代码,C语言实现网络嗅探器
- 利用随机矩阵理论(random matrix theory)确定微生物网络构建阈值
- BLE 技术(四)--- 链路层五种通信模式和空口协议设计 (Core_v5.2)
- Python练习题答案: 纳特拼音alaphabeta【难度:1级】--景越Python编程实例训练营,1000道上机题等你来挑战
- docker服务假死解决方案
- 搭建Cacti监控(2)
- (附源码)mysql+ssm学生选课系统 毕业设计 170920
- Mac安装指定版本的node
- Mac系统Safari浏览器快捷键大全
- arm_neon.h文件ABI说明
- NRC 0x78 在CAPL中如何打开和关闭