与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();
        }
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

□ 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");
        }
 
    }
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

□ 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 = "width:100px"})
    </p>
    <p>
        密码: @Html.Password("password", null, new {style = "width: 100px"})
    </p>
    <p>
        <input type="submit" name="login" value="登录"/>
    </p>
}
 

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

□ 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")

登录页:

登录失败:

□ 如果想在全局使用

filters.Add(new EncryptLoginAttribute());

□ 备注

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

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

MVC扩展Filter,通过继承ActionFilterAttribute为登录密码加密的更多相关文章

  1. MVC扩展Filter, 通过继承AuthorizationAttribute限制IP

    为什么需要AuthorizationAttribute 在没有Authorization系统属性之前,我们可能这样判断:Request.IsAuthenticated && User. ...

  2. MVC扩展Filter,通过继承HandleErrorAttribute,使用log4net或ELMAH组件记录服务端500错误、HttpException、Ajax异常等

    □ 接口 public interface IExceptionFilter{    void OnException(ExceptionContext filterContext);} Except ...

  3. 用RSA加密实现Web登录密码加密传输

    通常我们做一个Web应用程序的时候都需要登录,登录就要输入用户名和登录密码,并且,用户名和登录密码都是明文传输的,这样就有可能在中途被别人拦截,尤其是在网吧等场合. 这里顺带一个小插曲,我以前有家公司 ...

  4. laravel更改默认的登录密码加密方式

    laravel更改默认的登录密码加密方式   laravel 默认用的登录密码加密方式是: $password = Hash::make('password'); 而我平时用的密码加密方式是: $pa ...

  5. web登录密码加密

    文章:如何实现登录页面密码加密 文章:用RSA加密实现Web登录密码加密传输 文章:web登录用户名密码加密 知乎文章:Web前端密码加密是否有意义? 文章:记录一次黑客模拟攻击 成功拿到淘宝账号和密 ...

  6. 每日JS逆向练习之斗鱼登录密码加密,今天你练了吗?

    一切的基本功都是为后期调试滑块验证码准备的. 有兴趣的关注一下知识图谱与大数据公众号,当然不关注也无所谓.今天来看看斗鱼登录密码加密,正所谓熟能生巧,这种简单一点的基本3-5分钟就要能抠出来,有兴趣得 ...

  7. C#实现京东登录密码加密POST

    1.京东登录登录密码 function getEntryptPwd(pwd) { var pubKey = $('#pubKey').val(); if (!pwd || !pubKey || !Sy ...

  8. MVC扩展ModelBinder,通过继承DefaultModelBinder把表单数据封装成类作为action参数

    把视图省.市.街道表单数据,封装成一个类,作为action参数.如下: action方法参数类型: namespace MvcApplication1.Models{    public class ...

  9. shiro登录密码加密

    密码加密 String passwd = new SimpleHash("SHA-1", "username", "password").t ...

随机推荐

  1. mac上Python安装和修改Python默认路径遇到的问题

    此处例子是我使用homebrew安装了python3.6.1,建立一个符号链接,创建一个python3的命令,达到使用自己安装的python3的目的.此处不修改PATH,而是把需要添加的可执行文件或者 ...

  2. GUC-12 ScheduledThreadPool

    import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.Executors ...

  3. 基于Json.NET自己实现MVC中的JsonValueProviderFactory

    写了博文ASP.NET MVC 3升级至MVC 5.1的遭遇:“已添加了具有相同键的项”之后,继续看着System.Web.Mvc.JsonValueProviderFactory的开源代码. 越看越 ...

  4. Ionic实战五:ionic图表源码基于highcharts

    ionic图表demo基于Highcharts,highcharts 是一个用纯JavaScript编写的一个图表库, 能够很简单便捷的在web网站或是web应用程序添加有交互性的图表.HighCha ...

  5. ref:JAVA之Forward和Redirect的区别

    ref:https://www.cnblogs.com/selene/p/4518246.html 阅读目录 一:间接请求转发(Redirect) 二:直接请求转发(Forward) 用户向服务器发送 ...

  6. HDU - 1027 Ignatius and the Princess II 全排列

    Ignatius and the Princess II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ( ...

  7. Jvm内存区域和GC

    运行时数据区域 线程私有 程序计数器 正在执行的字节码指令的地址(native方法时为undefined) Java虚拟机栈 存储栈帧(局部变量表,操作数栈,动态链接,方法出口)OOM,StackOv ...

  8. JavaScript DOM大纲

    DOM 定义了访问和操作HTML文档的标准方法 访问(查找标签) ---- 直接查找 document.getElementById(“idname”) document.getElementsByT ...

  9. 1006 Sign In and Sign Out (25)(25 point(s))

    problem At the beginning of every day, the first person who signs in the computer room will unlock t ...

  10. Python内存管理方式和垃圾回收算法解析

    在列表,元组,实例,类,字典和函数中存在循环引用问题.有 __del__ 方法的实例会以健全的方式被处理.给新类型添加GC支持是很容易的.支持GC的Python与常规的Python是二进制兼容的. 分 ...