您的位置:首页 > 其它

MVC扩展Filter,通过继承ActionFilterAttribute为登录密码加密

2014-05-27 11:12 218 查看
与ActionFilter相关的接口有2个:

□IActionFilter对action执行前后处理

voidOnActionExecuting(ActionExecutingContextfilterContext);
可以在此对请求处理,甚至开启一个新的请求。

voidOnActionExecuted(ActonExecutedContextfilterContext);
可以在此对返回结果处理,甚至取消返回结果。

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

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

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

方法与属性与IActionFilter类似。
voidOnResultExecuted(ResultExecutedContextfilterContext);
voidOnResultExecuting(ResultExecutingContextfilterContext);

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

ActionFilterAttribute包含了如下4个方法:
voidOnActionExecuting(ActionExecutingContextfilterContext);
voidOnActionExecuted(ActonExecutedContextfilterContext);
voidOnResultExecuted(ResultExecutedContextfilterContext);
voidOnResultExecuting(ResultExecutingContextfilterContext);
所以,我们可以在派生类中重写这4个方法。

□思路

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

□继承ActionFilterAttribute

usingSystem;
usingSystem.Security.Cryptography;
usingSystem.Text;
usingSystem.Web.Mvc;
usingSystem.Web.Security;
namespaceMvcApplication1.Extension
{
publicclassEncryptLoginAttribute:ActionFilterAttribute
{
privatestringusername;
privatestringpassword;
privateboolisAuthorized=false;
privatestringlongdate;
privatestringlastTry;
publicoverridevoidOnActionExecuting(ActionExecutingContextfilterContext)
{
username=filterContext.HttpContext.Request.Form["username"];
password=filterContext.HttpContext.Request.Form["password"];
MD5md5Hash=MD5.Create();
stringmd5Password=GetMD5Hash(md5Hash,password);
boolresult=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();
}
}
publicoverridevoidOnActionExecuted(ActionExecutedContextfilterContext)
{
if(isAuthorized)
{
filterContext.Result=newViewResult(){ViewName="Welcome"};
}
else
{
ViewResultresult=newViewResult();
result.ViewName="Index";
result.ViewBag.message="Loginfail";
filterContext.Result=result;
}
}
publicoverridevoidOnResultExecuted(ResultExecutedContextfilterContext)
{
if(filterContext.Exception==null&&!filterContext.Canceled)
{
ViewResultresult=(ViewResult)filterContext.Result;
if(result!=null)
{
if(result.ViewName=="Welcome")
{
filterContext.HttpContext.Response.Write("<pstyle='color:Green;'><br/>Todayis"
+longdate+"<br/></p>");
}
elseif(result.ViewName=="Index")
{
filterContext.HttpContext.Response.Write("<pstyle='color:Red;'><br/>LastLoginattempat"+lastTry+"<br/></p>");
}
filterContext.Result=result;
}
}
}
privatestaticstringGetMD5Hash(MD5md5Hash,stringinput)
{
//string→byte[]
byte[]data=md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilderstringBuilder=newStringBuilder();
foreach(bytebindata)
{
stringBuilder.Append(b.ToString("x2"));
}
returnstringBuilder.ToString();
}
}
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{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

usingSystem.Web.Mvc;
usingSystem.Web.Security;
usingMvcApplication1.Extension;
namespaceMvcApplication1.Controllers
{
publicclassHomeController:Controller
{
publicActionResultIndex()
{
returnView();
}
[HttpPost]
[EncryptLogin]
publicActionResultLogin(stringusername,stringpassword)
{
//TODO:保存到数据库
returnnull;
}
publicActionResultSignOut()
{
FormsAuthentication.SignOut();
returnRedirectToAction("Index");
}
}
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{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>
<pstyle="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>
<inputtype="submit"name="login"value="登录"/>
</p>
}

.csharpcode,.csharpcodepre
{
font-size:small;
color:black;
font-family:consolas,"CourierNew",courier,monospace;
background-color:#ffffff;
/*white-space:pre;*/
}
.csharpcodepre{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相关配置

<authenticationmode="Forms">
<formsloginUrl="~/Home/Index"timeout="2880">
<credentialspasswordFormat="Clear">
<username="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(newEncryptLoginAttribute());

□备注

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

参考资料:
MVCFiltersPart3-ActionFilterandActionResultFilter
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: