我正在尝试使用表单身份验证在ASP.NET MVC中创建自定义身份验证方案.我可能在网站上有不同区域的想法 – 审批者是和一般用户区域,这些将使用不同的登录页面,等等.所以这就是我想要发生的事情.
>用户访问受限页面(现在我用客户AuthorizeAttribute保护它)
>用户被重定向到特定的登录页面(不是Web.config中的登录页面).
>验证用户凭据(通过自定义数据库方案)和用户登录.
非常感谢任何帮助!
这就是我到目前为止所做的,它不起作用:
public class AdministratorAccountController : Controller { public ActionResult Login() { return View("Login"); } [HttpPost] public ActionResult Login(AdministratorAccountModels.LoginModel model,string returnUrl) { if (ModelState.IsValid) if (model.UserName == "admin" && model.Password == "pass") // This will be pulled from DB etc { var ticket = new FormsAuthenticationTicket(1,// version model.UserName,// user name DateTime.Now,// create time DateTime.Now.AddSeconds(30),// expire time false,// persistent ""); // user data var strEncryptedTicket = FormsAuthentication.Encrypt(ticket); var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,strEncryptedTicket); Response.Cookies.Add(cookie); if (!String.IsNullOrEmpty(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index","Home"); } } else { ModelState.AddModelError("","The user name or password provided is incorrect."); } // If we got this far,something Failed,redisplay form return View(model); } [AdministratorAuthorize] public ActionResult MainMenu() { return View(); } public class AdministratorAuthorizeAttribute : AuthorizeAttribute { protected override bool AuthorizeCore(HttpContextBase httpContext) { var authenCookie = httpContext.Request.Cookies.Get(FormsAuthentication.FormsCookieName); if (authenCookie == null) return false; var ticket = FormsAuthentication.Decrypt(authenCookie.Value); var id = new FormsIdentity(ticket); var astrRoles = ticket.UserData.Split(new[] { ',' }); var principal = new GenericPrincipal(id,astrRoles); httpContext.User = principal; return true; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { var model = new AdministratorAccountModels.LoginModel(); var viewData = new ViewDataDictionary(model); filterContext.Result = new ViewResult { ViewName = "Login",ViewData = viewData }; } } }
解决方法
我使用了减号和上面我自己的代码建议的代码组合来创建这个可能对其他人有帮助的简化方案.我添加了一些关于最初让我困惑的事情的评论.
public class AdministratorAccountController : Controller { public ActionResult Login() { return View("Login"); } [HttpPost] public ActionResult Login(AdministratorAccountModels.LoginModel model,string returnUrl) { if (ModelState.IsValid) // Here you would call a service to process your authentication if (model.UserName == "admin" && model.Password == "pass") { // * !!! * // Creating a FromsAuthenticationTicket is what // will set RequestContext.HttpContext.Request.IsAuthenticated to True // in the AdminAuthorize attribute code below // * !!! * var ticket = new FormsAuthenticationTicket(1,// persistent ""); // user data,such as roles var strEncryptedTicket = FormsAuthentication.Encrypt(ticket); var cookie = new HttpCookie(FormsAuthentication.FormsCookieName,strEncryptedTicket); Response.Cookies.Add(cookie); // Redirect back to the page you were trying to access if (!String.IsNullOrEmpty(returnUrl)) { return Redirect(returnUrl); } else { return RedirectToAction("Index",redisplay form return View(model); } [AdminAuthorize] public ActionResult MainMenu() { return View(); } public class AdminAuthorize : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { if (!filterContext.RequestContext.HttpContext.Request.IsAuthenticated) { // Redirect to the needed login page // This can be pulled from config file or anything else filterContext.HttpContext.Response.Redirect("/AdministratorAccount/Login?ReturnUrl=" + HttpUtility.UrlEncode(filterContext.HttpContext.Request.RawUrl)); } base.OnActionExecuting(filterContext); } } }