代码的执行顺序是 OnAuthorization–>AuthorizeCore–>HandleUnauthorizedRequest. 如果AuthorizeCore返回false时,才会走HandleUnauthorizedRequest 方法,并且Request.StausCode会返回401。
首先创建一个MCV的项目,在App_Start目录下创建一个类UserAuthAttribute,此类要继承AuthorizeAttribute类,这里继承的时候注意using System.Web.Mvc;
接着在App_Start目录下找到 FilterConfig类,添加注册。
登陆页面:
<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>LogIn</title> </head> <body> <div style=" 600px; margin:50px auto;"> <form action="/Account/LogIn" method="post"> <table> <tr><td>User Name</td><td><input type="text" id="username" name="username" /></td></tr> <tr><td>Pass word</td><td><input type="password" id="password" name="password" /></td></tr> <tr><td></td><td><input type="submit" value="LogIn" /></td></tr> </table> </form> </div> </body> </html>
登陆后台
[AllowAnonymous] public ActionResult LogIn() { string User_Name = this.Request.Form["username"]; string User_Pw = this.Request.Form["password"]; if (!string.IsNullOrEmpty(User_Name) && !string.IsNullOrEmpty(User_Pw)) { List<User> Ulist = TestData.Users; var userinfos = Ulist.Where(e => e.UserName.Equals(User_Name) && e.PassWord.Equals(User_Pw)); if (userinfos != null && userinfos.Count() == 1) { User _user = userinfos.FirstOrDefault(); Session[WebConstants.UserSession] = _user; Session[WebConstants.UserRoleMenu] = TestData.GetMenuByUserID(_user.UserID); string fromurl = Request.UrlReferrer.Query; if (fromurl.IndexOf("?fromurl=") > -1) { fromurl = fromurl.Substring(9); return this.Redirect(fromurl); } else { return this.RedirectToAction("Home", "Account"); } } } return View(); }
注意:LogIn()加了标识 [AllowAnonymous] ,表示允许任何用户访问.
登陆完成后,session记录用户信息和可访问的Menu信息,跳转到主页或者先前页。
最重要的一个环节就是之前创建的UserAuthAttribute这个类:
在类里先定义个变量
public bool IsLogin = false;
验证是否已经登陆,判定是否有权限
protected override bool AuthorizeCore(HttpContextBase httpContext) { bool Pass = false; try { var websession = httpContext.Session[WebConstants.UserSession]; if (websession == null) { httpContext.Response.StatusCode = 401;//无权限状态码 Pass = false; IsLogin = false; } else { User user = httpContext.Session[WebConstants.UserSession] as User; if (user == null) { httpContext.Response.StatusCode = 401;//无权限状态码 Pass = false; IsLogin = false; } else if (!IsMenuRole(httpContext)) { httpContext.Response.StatusCode = 401;//无权限状态码 Pass = false; IsLogin = true; } else { Pass = true; } } } catch (Exception) { return Pass; } return Pass; }
当上面这个方法返回false时才会执行下面这个方法, 进行跳转, 若没登陆,跳转到登陆页并带有参数,当登陆完成后可以跳转的先前页。这URL可以使用加密,防止客户修改或传递的参数发生编码错误。
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } else { if (!IsLogin) { string fromUrl = filterContext.HttpContext.Request.Url.PathAndQuery; // string strUrl = new UrlHelper(filterContext.RequestContext).Action("Login", "Account","") + "?fromurl={0}"; string strUrl = "~/Account/Login/?fromurl={0}"; //filterContext.HttpContext.Response.Redirect(string.Format(strUrl, fromUrl), true);
filterContext.Result = new RedirectResult(string.Format(strUrl, fromUrl)); } else { filterContext.Result = new RedirectResult("~/Account/NoPremission"); } } }