zoukankan      html  css  js  c++  java
  • MVC扩展Filter,通过继承ActionFilterAttribute为登录密码加密


    与ActionFilter相关的接口有2个:

     

    □ IActionFilter 对action执行前后处理

    void OnActionExecuting(ActionExecutingContext filterContext);
    可以在此对请求处理,甚至开启一个新的请求。

    void OnActionExecuted(ActonExecutedContext filterContext);
    可以在此对返回结果处理,甚至取消返回结果。

    关于参数ActionExecutingContext和ActonExecutedContext共有的:
    都继承于ControllerContext。
    都有ActionDescriptor属性:提供了action的细节
    都有ActionResult属性:当设置为null的时候取消整个请求

    关于ActonExecutedContext独有的:
    Canceled属性:bool类型,ActionExecutedContext是否被其它action filter取消
    Exception属性:action filter和action抛出的异常
    ExceptionHandled属性:bool类型,异常是否被处理

    □ IResultFilter 对action返回结果前后做处理

    方法与属性与IActionFilter类似。
    void OnResultExecuted(ResultExecutedContext filterContext);
    void OnResultExecuting(ResultExecutingContext filterContext);

      实例:继承ActionFilterAttribute为登录密码加密

    ActionFilterAttribute包含了如下4个方法:
    void OnActionExecuting(ActionExecutingContext filterContext);
    void OnActionExecuted(ActonExecutedContext filterContext);
    void OnResultExecuted(ResultExecutedContext filterContext);
    void OnResultExecuting(ResultExecutingContext filterContext);
    所以,我们可以在派生类中重写这4个方法。

    □ 思路

    →在执行action之前对密码加密
    →在执行action之后,根据是否登录成功,来决定返回成功或重新登录视图
    →在action返回结果之后,再追加一些内容

    □ 继承ActionFilterAttribute

    using System;
    using System.Security.Cryptography;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.Security;
     
    namespace MvcApplication1.Extension
    {
        public class EncryptLoginAttribute : ActionFilterAttribute
        {
            private string username;
            private string password;
            private bool isAuthorized = false;
            private string longdate;
            private string lastTry;
     
            public override void OnActionExecuting(ActionExecutingContext filterContext)
            {
                username = filterContext.HttpContext.Request.Form["username"];
                password = filterContext.HttpContext.Request.Form["password"];
                MD5 md5Hash = MD5.Create();
                string md5Password = GetMD5Hash(md5Hash, password);
                bool result = Membership.ValidateUser(username, md5Password);
                if (result)
                {
                    FormsAuthentication.SetAuthCookie(username, false);
                    isAuthorized = true;
                    longdate = DateTime.Now.ToLongDateString();
                }
                else
                {
                    isAuthorized = false;
                    lastTry = DateTime.Now.ToShortDateString() + "-" + DateTime.Now.ToShortTimeString();
                }
            }
     
            public override void OnActionExecuted(ActionExecutedContext filterContext)
            {
                if (isAuthorized)
                {
                    filterContext.Result = new ViewResult(){ViewName = "Welcome"};
                }
                else
                {
                    ViewResult result = new ViewResult();
                    result.ViewName = "Index";
                    result.ViewBag.message = "Login fail";
                    filterContext.Result = result;
                }
            }
     
            public override void OnResultExecuted(ResultExecutedContext filterContext)
            {
                if (filterContext.Exception == null && !filterContext.Canceled)
                {
                    ViewResult result = (ViewResult)filterContext.Result;
                    if (result != null)
                    {
                        if (result.ViewName == "Welcome")
                        {
                            filterContext.HttpContext.Response.Write("<p style='color:Green;'><br/>Today is "
    + longdate + "<br/></p>");
                        }
                        else if (result.ViewName == "Index")
                        {
                            filterContext.HttpContext.Response.Write("<p style='color:Red;'><br />Last Login attemp at "+lastTry+"<br/></p>");
                        }
                        filterContext.Result = result;
                    }
                }
            }
     
            private static string GetMD5Hash(MD5 md5Hash, string input)
            {
                //string→byte[]
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
                StringBuilder stringBuilder = new StringBuilder();
                foreach (byte b in data)
                {
                    stringBuilder.Append(b.ToString("x2"));
                }
                return stringBuilder.ToString();
            }
        }
    }
     

    □ HomeController

    using System.Web.Mvc;
    using System.Web.Security;
    using MvcApplication1.Extension;
     
    namespace MvcApplication1.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                return View();
            }
     
            [HttpPost]
            [EncryptLogin]
            public ActionResult Login(string username, string password)
            {
                //TODO:保存到数据库
                return null;
            }
     
            public ActionResult SignOut()
            {
                FormsAuthentication.SignOut();
                return RedirectToAction("Index");
            }
     
        }
    }
     

    □ Home/Index.cshtml为登录页

    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
     
    <h2>Index</h2>
    <p style="color: red;">@ViewBag.message</p>
    @using (Html.BeginForm("Login", "Home", FormMethod.Post, new {id = "loginForm"}))
    {
        <p>
            用户名:@Html.TextBox("username", null, new {style = "100px"})
        </p>
        <p>
            密码: @Html.Password("password", null, new {style = " 100px"})
        </p>
        <p>
            <input type="submit" name="login" value="登录"/>
        </p>
    }
     

    □ web.config相关配置

        <authentication mode="Forms">
          <forms loginUrl="~/Home/Index" timeout="2880">
            <credentials passwordFormat="Clear">
              <user name="name" password="21218cca77804d2ba1922c33e0151105"/>
            </credentials>
          </forms>
        </authentication>

    □ 登录成功视图:/Shared/Welcome.cshtml

    @{
        ViewBag.Title = "Welcome";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }

    <h2>登录成功~~</h2>
    @Html.ActionLink("登出","SignOut","Home")

    登录页:

    1

    登录失败:

    3

    □ 如果想在全局使用

    filters.Add(new EncryptLoginAttribute());

    □ 备注

    暂没有把登录成功显示页面调试出来,因为,当使用FormsAuthentication.Authenticate(username, md5Password)时,提示此方法已经过时;而使用Membership.ValidateUser(username, md5Password)时,对应的Web.config如何配置,暂没细究。

    参考资料:
    MVC Filters Part 3 - Action Filter and Action Result Filter

  • 相关阅读:
    nginx+ftp图片服务器搭建
    第一篇随笔
    字符设备控制技术
    总结字符设备
    字符设备驱动模型
    使用字符设备驱动
    驱动开发前奏
    linux内核链表的移植与使用
    linux内存管理子系统
    内核模块可选信息
  • 原文地址:https://www.cnblogs.com/darrenji/p/3754713.html
Copyright © 2011-2022 走看看