使用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.PasswordFor(model=>model.Password,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 有哪里寫的不對還請指出