MVC擴充Filter,通過繼承ActionFilterAttribute為登入密碼加密

來源:互聯網
上載者:User

標籤:des   style   c   class   blog   code   


與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 = "width:100px"})
    </p>
    <p>
        密碼: @Html.Password("password", null, new {style = "width: 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")

 

登入頁:

 

 

登入失敗:

 

□ 如果想在全域使用

filters.Add(new EncryptLoginAttribute());

 

□ 備忘

暫沒有把登入成功顯示頁面調試出來,因為,當使用FormsAuthentication.Authenticate(username, md5Password)時,提示此方法已經過時;而使用Membership.ValidateUser(username, md5Password)時,對應的Web.config如何配置,暫沒細究。

 

參考資料:
MVC Filters Part 3 - Action Filter and Action Result Filter

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.