本博文主要讲解 在ASP.NET MVC 开发中,基于表单的身份验证(Forms Authentication)来实现登录功能。虽然是在4.0下实现的,但是用到4.0的东西并不多
1. 表单身份验证思路
表单的身份验证原理是比较简单的。
在用户验证完用户名和密码后,向浏览器记录 一个 加密的Cookie(其中包含用户的用户信息,过期时间,自定义信息等内容)。 而后 配合过滤器,在控制器或Action前加上 身份验证的特性 ,对请求进行拦截。 拦截后,分析请求的Cookie ,若已登录,则进入Cookie,若未登录或登录过期则跳转 预定的登录页。
2. 实现功能描述
基本的登录功能:未登录 或 登录过期 或退出系统 后,跳转到登录页。 将用户的基本信息(ID, 头像,用户名等内容)显示到 模板页中(_Layout 中)。 可以直接在有身份验证的页面,使用用户名及其他保存的信息
3. 实现步骤
第一步: 配置WebConfig - <system.web>
- <!--<authentication mode="None" /> delete by wys -->
- <authentication mode="Forms">
- <forms name=".ASPXAUTH" loginUrl="/account/login" defaultUrl="/home/index" protection="All" timeout="30" path="/" requireSSL="false" slidingExpiration="true" enableCrossAppRedirects="false" cookieless="UseDeviceProfile" domain="" />
- </authentication>
- ...
- <system.web>
复制代码
简单介绍一下配置中的几个参数:
官方文档: http://msdn2.microsoft.com/zh-cn/library/1d3t3c61(VS.85).aspx - name=".ASPXAUTH" // Cookie的名字 FormsAuthentication.FormsCookieName
- loginUrl="/account/login" // 登录页的访问地址 FormsAuthentication.LoginUrl
- protection="All" //Cookie的保护模式,可取值包括All(同时进行加密和数据验证)、Encryption(仅加密)、Validation(仅进行数据验证)和None。为了安全,该属性通常从不设置为None。
- timeout="30" // cookie 的过期时间
- path="/" // cookie 的路径
- requireSSL="false" //在进行Forms Authentication时,与服务器交互是否要求使用SSL。可以通过FormsAuthentication.RequireSSL属性得到该配置值。
- slidingExpiration="true" // 弹性过期时间
- //是否启用“弹性过期时间”,如果该属性设置为false,从首次验证之后过timeout时间后Cookie即过期;如果该属性为true,则从上次请求该开始过timeout时间才过期,这意味着,在首次验证后,如果保证每timeout时间内至少发送一个请求,则Cookie将永远不会过期。通过FormsAuthentication.SlidingExpiration属性可以得到该配置值。
- enableCrossAppRedirects = false;
- //是否可以将以进行了身份验证的用户重定向到其他应用程序中。通过FormsAuthentication.EnableCrossAppRedirects属性可以得到该配置值。为了安全考虑,通常总是将该属性设置为false。
- cookieless="UseDeviceProfile"
- // cookieless——定义是否使用Cookie以及Cookie的行为。Forms Authentication可以采用两种方式在会话中保存用户凭据信息,一种是使用Cookie,即将用户凭据记录到Cookie中,每次发送请求时浏览器都会将该Cookie提供给服务器。另一种方式是使用URI,即将用户凭据当作URL中额外的查询字符串传递给服务器。该属性有四种取值——UseCookies(无论何时都使用Cookie)、UseUri(从不使用Cookie,仅使用URI)、AutoDetect(检测设备和浏览器,只有当设备支持Cookie并且在浏览器中启用了Cookie时才使用Cookie)和UseDeviceProfile(只检测设备,只要设备支持Cookie不管浏览器是否支持,都是用Cookie)。通过FormsAuthentication.CookieMode属性可以得到该配置值。通过FormsAuthentication.CookiesSupported属性可以得到对于当前请求是否使用Cookie传递用户凭证。
- domain="" //Cookie的域。FormsAuthentication.CookieDomain
- //以上针对<system.web>/<authentication>/<forms>节点的介绍非常简略,基本上是Anders Liu个人对于文档进行的额外说明。有关<forms>节点的更多说明,请参见MSDN文档(http://msdn2.microsoft.com/zh-cn/library/1d3t3c61(VS.85).aspx)。
复制代码
- public static void RedirectToLoginPage () // 跳转到登录页,自带ReturnUrl 参数
- public static void RedirectToLoginPage (string extraQueryString) // 可以自定义参数
- public static void RedirectFromLoginPage (string userName, bool createPersistentCookie)
- public static void RedirectFromLoginPage (string userName, bool createPersistentCookie, string strCookiePath)
- // 可以创建Cookie ,createPersistentCookie ,“记住我”,详情参考下面的博文
复制代码
博文参考:Forms Authentication基础知识
登录控制器方法编写 - /// <summary>
- /// 登录方法
- /// </summary>
- /// <param name="model">登录模型</param>
- /// <param name="returnUrl">后台管理系统</param>
- /// <returns></returns>
- [HttpPost]
- [ValidateAntiForgeryToken]
- public ActionResult Login(LoginViewModel model,string returnUrl="")
- {
- if (!ModelState.IsValid)
- {
- return View(model);
- }
- bool status = Request.IsAuthenticated;
- // 1.验证用户名 和 密码
- En.AdminUser adminUser = Da.AdminUserDB.ValidateLogin(model.UserName, model.Password);
- //2.用它来序列化要对象
- JavaScriptSerializer serial = new JavaScriptSerializer();
- //3.判断用户是否存在,且用户状态正常
- if (adminUser != null && adminUser.State != 1)
- {
- //4. 用户描述用户基本信息
- AdminModel userInfo = new AdminModel()
- {
- ID = adminUser.ID,
- UserName = adminUser.UserName,
- RoleID = adminUser.RoleID,
- Portrait = adminUser.Portrait
- };
- //5. 生成初始化凭据
- FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
- 1,
- model.UserName,
- DateTime.Now,
- DateTime.Now.AddMinutes(30),
- false,
- serial.Serialize(userInfo)
- );
- //6. 加密
- string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
- //7. 响应到客户端
- System.Web.HttpCookie authCookie = new System.Web.HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
- System.Web.HttpContext.Current.Response.Cookies.Add(authCookie);
- //8. 返回首页, 也可以跳回 RetureUrl
- return RedirectToLocal("~/");//自定义方法,返回首页
- }
- else if (adminUser != null && adminUser.State == 1)
- {
- TempData["message"] = "该账户已被注销!";
- return View();
- }
- else
- {
- TempData["message"] = "用户名或密码错误!";
- return View();
- }
- }
复制代码
每一步的操作,我已经备注在代码里。 简单来说,就是生成凭据,而后种到客户端。有了凭据之后,下面介绍凭据的验证。
检验是否登录的过滤器
思路: 继承一个过滤器,复写OnActionExecuting(Action执行之前)方法,使用 Request.IsAuthenticated 判断是否已验证成功。
如果已验证: 取出我们存储的自定义信息,并把它 放到 ViewData 里,这样我们在页面里,便可以直接用了。如果只是简单使用用户名之可以 直接使用【 User.Identity.Name】
- /// <summary>
- /// 登录身份验证
- /// </summary>
- public class AuthenticationAttribute : ActionFilterAttribute
- {
- public override void OnActionExecuting(ActionExecutingContext filterContext)
- {
- if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated)
- {
- //未登录的时候,此处加了一个判断,判断同步请求还是一部请求
- if (filterContext.HttpContext.Request.IsAjaxRequest())
- {
- //异步请求,返回JSON数据
- filterContext.Result = new JsonResult
- {
- Data = new
- {
- Status = -1,
- Message = "登录已过期,请刷新页面后操作!"
- },
- JsonRequestBehavior = JsonRequestBehavior.AllowGet
- };
- }
- else
- {
- //非异步请求,则跳转登录页
- FormsAuthentication.RedirectToLoginPage();//重定向会登录页
- }
- }
- else
- {
- //1.登录状态获取用户信息(自定义保存的用户)
- var cookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName];
- //2.使用 FormsAuthentication 解密用户凭据
- var ticket = FormsAuthentication.Decrypt(cookie.Value);
- AdminModel loginUser = new AdminModel();
- //3. 直接解析到用户模型里去,有没有很神奇
- loginUser = new JavaScriptSerializer().Deserialize<AdminModel>(ticket.UserData);
- //4. 将要使用的数据放到ViewData 里,方便页面使用
- filterContext.Controller.ViewData["UserName"] = loginUser.UserName;
- filterContext.Controller.ViewData["Portrait"] = loginUser.Portrait;
- filterContext.Controller.ViewData["UserID"] = loginUser.ID;
- }
- // 别忘了这一句。
- base.OnActionExecuting(filterContext);
- }
- }
复制代码
使用身份验证
在写完上面两个步骤后,身份验证对我们来说,已经很简单了。我们可以 直接在 类上上面加上 身份验证的【特性】,这样这个类都会进行身份验证,当然也可以加载Action 上,这样Action 就会有相应的身份验证。 例如:
退出功能
退出功能,直接使用下面代码即可,SignOut 注销cookie信息,RedirectToLoginPage跳回登录页 - /// <summary>
- /// 注销方法,退出登录
- /// </summary>
- public void logOut()
- {
- FormsAuthentication.SignOut();
- FormsAuthentication.RedirectToLoginPage();
- }
复制代码
参考博文
http://www.cnblogs.com/AndersLiu/archive/2008/01/01/forms-authentication-part-1.html 来源:https://blog.csdn.net/shuai_wy/article/details/78126080 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |