使用asp.net mvc 实现登陆及角色验证。
我最进想要实现对网站登陆者的权限管理问题,不同角色的用户访问页面收到权限的限制。然而因为建立的是空项目,所以只能手动实现角色管理的功能。
基本的思想就是重载AuthorizeAttribute特性标签,让重载的类继承ActioFilterAttribute类来实现个性的角色验证标签。
而登陆controller的书写主要就是从数据库中查出用户信息并把登陆信息用ticket加密保存在cookie里。
下面这段代码是登陆的控制器代码
namespace AccessControlSystem.Controllers { public class AccessController : Controller { private AccessControlContext db = new AccessControlContext(); [HttpGet] public ActionResult login() { return View(); } [HttpPost] [ValidateAntiForgeryToken] public ActionResult login(Login login) { var users = db.Users.Where(a => a.Name == login.UserName); if (!users.Any()) return View(); User user = users.First(); var cards = db.Cards.Where(a => a.User_id == user.Id); Card card = cards.First(); if(login.Password=="123"&&card.Privilege==2) { FormsAuthenticationTicket Ticket = new FormsAuthenticationTicket( 1, login.UserName, DateTime.Now, DateTime.Now.AddMinutes(20), false, "admin" ); var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(Ticket)); cookie.HttpOnly = true; HttpContext.Response.Cookies.Add(cookie); return RedirectToAction("../DataBase/SelectUser"); } return RedirectToAction("login"); } } }
使用[HttpPost]来提交表单,其中login只用一个变量,其实还可以加一个string returnUrl的变量使用Redirect()方法重定向到之前不具有权限的页面。
上面这段代码的核心部分是if中的代码,FormsAuthenticationTicket.ticket是我们要用来加密的票据,其中较重要的是login.UserName,和"admin"分别存放在ticket的name,userData中。
然后将加密(FormsAuthentication.Encrypt(Ticket))后的票据存在cookie的value中。
下面这段代码是对于AuthorizeAttribute的重载
namespace AccessControlSystem.Controllers { public class AuthenticationAttribute:ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { string role = ""; var cookie = filterContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName]; if (cookie != null) { var ticket = FormsAuthentication.Decrypt(cookie.Value); role = ticket.UserData; } if (role.Length==0||role!="admin") { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { Controller = "Access", action = "login" })); } base.OnActionExecuting(filterContext); } } }
这段代码中我们从filterContext中读取cookie的值,让后通过FormsAuthentication.Decrypt(cookie.Value)解密出票据信息,票据中的userData存放了我们用户的权限。
定义完此类之后我们就可以在其他方法之前添加[Authentication]特性标签来筛选用户的权限,在此实例中只有拥有“admin”的用户才能访问,当然我并没有用[Authentication(Role="admin")]的方法
因为我还没有研究如何继承RoleProvider或者如何实现IPrincipal接口,所以没有使用Role我应该会在之后更新这两个方法的实现方法。
下面是我定义的登陆界面
@model AccessControlSystem.Models.Login @{ ViewBag.Title = "View"; } <h2>Login</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken(); @Html.ValidationSummary(true,"",new { @class="text-danger"}) <fieldset class="form-horizontal"> <div class="form-group"> @Html.LabelFor(model=>model.UserName,htmlAttributes:new {@class="control-label col-md-2"}) <div class="col-md-10"> @Html.EditorFor(model=>model.UserName,new { htmlAttributes=new { @class="form-control"} }) @Html.ValidationMessageFor(model=>model.UserName,"",new {@class="text-danger"}) </div> </div> <div class="form-group"> @Html.LabelFor(model=>model.Password, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model=>model.Password,new { htmlAttributes=new { @class="form-control"} }) @Html.ValidationMessageFor(model=>model.UserName,"",new { @class="text-danger"}) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Submit" class="btn btn-default" /> </div> </div> </fieldset> }
由于是刚刚接触asp.net mvc 有哪里写的不对还请指出