如何使用ASP.NET MVC Framework Preview 2 中ActionFilterAttribute属性设计Form用户验证
首先采用BaseController继承Controller以改写保护方法RedirectToAction为公有方法(用以在ActionFilterAttribute属性中使用),本例中扩展了两个属性RequireLoginAttribute 、 RequireRoleAttribute;在RequireLoginAttribute属性过滤中重定向为登录的用户到登录窗户、在 RequireRoleAttribute属性过滤中将非该用户角色的操作显示访问拒绝信息,具体代码如下:
基础请看 David Hayden [MVP C#] 的 actionfilterattribute-in-asp-net-mvc-framework
This code is my extended ActionFilterAttribute as RequireLoginAttribute and RequireRoleAttribute for form authentication, I just write the BaseController to public the Controller's RedirectToAction function for use it in extended ActionFilterAttribute.
Just for fun with coding!
namespace Bolik.Web.Mvc { using System; using System.Web.Mvc; using System.Threading; public class BaseController : Controller { protected override void Execute(ControllerContext controllerContext) { try { base.Execute(controllerContext); } catch (Exception e) { if (!(e is ThreadAbortException)) { ViewData["ErrorMessage"] = e.Message; RenderView("Error", ViewData); } } } public new void RedirectToAction(string actionName, string controllerName) { base.RedirectToAction(actionName, controllerName); } } public class RequireLoginAttribute : ActionFilterAttribute { public override void OnActionExecuting(FilterExecutingContext filterContext) { if (filterContext.Controller is BaseController) { var b = filterContext.Controller as BaseController; if (b != null) { if (!b.User.Identity.IsAuthenticated) { filterContext.Cancel = true; b.RedirectToAction("Login", "Security"); } } } base.OnActionExecuting(filterContext); } } public class RequireRoleAttribute : ActionFilterAttribute { private readonly string _RoleName; public RequireRoleAttribute(string roleName) { _RoleName = roleName; } public override void OnActionExecuting(FilterExecutingContext filterContext) { if (filterContext.Controller is BaseController) { var b = filterContext.Controller as BaseController; if (b != null) { if (!b.User.IsInRole(_RoleName)) { filterContext.Cancel = true; b.RedirectToAction("AccessDenied", "Error"); } } } base.OnActionExecuting(filterContext); } } }
使用代码如下:
namespace Bolik.Controllers { using System; using System.Web.Security; using System.Web.Routing; using System.Web.Mvc;
using Bolik.Web.Mvc; using Binding = System.Web.Mvc.BindingHelperExtensions; public class HomeController : BaseController { public void Index(string name) { RenderView("Index"); } public void About() { RenderView("About") } public void FourOhFour() { throw new ArgumentException(); } public void FiveOhOh() { throw new ApplicationException(); } [RequireLogin] public void Secure() { RenderView("Secure"); } [RequireRole("Administrator")] public void AdminsOnly() { RenderView("AdminsOnly"); } } public class SecurityController : BaseController { public void Login() { RenderView("Login"); } [RequireLogin] public void Logout() { FormsAuthentication.SignOut(); Response.Redirect("/"); } public void Authenticate() { string userName = Request.Form["userName"]; string password = Request.Form["password"]; string rememberMe = Request.Form["rememberMe"]; if (Membership.ValidateUser(userName, password)) { FormsAuthentication.SetAuthCookie(userName, (rememberMe != null)); RedirectToAction("index", "Home"); } } } }