概念介紹
認證過濾器是MVC5的新特性,它有一個相對復雜的生命周期,它在其他所有過濾器之前運行,我們可以在認證過濾器中創建一個我們定義的認證方法,也可以結合授權過濾器做一個復雜的認證方法,這個方法可以不准守授權規則。認證過濾器還可以在一個動作方法執行后,處理前運行。
如果我們需要創建認證過濾器需要實現IAuthenticationFilter接口。
namespace System.Web.Mvc.Filters
{
//
// 摘要:
// 定義一個用於執行身份驗證的篩選器。
public interface IAuthenticationFilter
{
//
// 摘要:
// 對請求進行身份驗證。
//
// 參數:
// filterContext:
// 用於身份驗證的上下文。
void OnAuthentication(AuthenticationContext filterContext);
//
// 摘要:
// 向當前 System.Web.Mvc.ActionResult 添加身份驗證質詢。
//
// 參數:
// filterContext:
// 用於身份驗證質詢的上下文。
void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext);
}
}
我們看到該接口里有兩個方法OnAuthentication和OnAuthenticationChallenge,前者在運行其他類型的過濾器之前調用,后者無論對認證的請求或對動作方法授權的請求失敗都會調用
OnAuthentication方法
我們已經知道了OnAuthentication方法在所有過濾器運用之前被調用,在OnAuthentication方法中傳遞的參數是一個AuthenticationContext對象,它繼承於ControllerContext類,它的屬性如下:
名稱 | 類型 | 說明 |
---|---|---|
ActionDescriptor | ActionDescriptor | 獲取或設置操作描述符。 |
Principal | IPrincipal | 獲取或設置當前已進行身份驗證的主體。 |
Result | ActionResult | 獲取或設置由操作方法返回的結果。 |
執行OnAuthentication方法
下面我將演示OnAuthentication方法,首先我們還是在之前的Filter文件夾下添加一個名為 CustomAuthAttribute.cs 的過濾器類,我們繼承 FilterAttribute 類和 IAuthenticationFilter 接口,為了方便演示,我們簡單處理,判斷請求類型,如果是本地請求那么我們讓其回到登錄頁。
這是我們在_CustomAuthAttribute.cs_ 文件中編寫的代碼
public class CustomActionAttribute : FilterAttribute, IActionFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
var user = filterContext.HttpContext.Request.IsLocal;
if (user)
{
var Url = new UrlHelper(filterContext.RequestContext);
var url = Url.Action("Login", "Account");
filterContext.Result = new RedirectResult(url);
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
}
}
接着我們在Home控制器里修改About()方法,在方法上方加上我們的過濾器
[CustomAuth]
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return View();
}
好了我們運行程序,看看效果
OnAuthenticationChallenge方法
OnActionExecuted方法無論對認證的請求或對動作方法授權的請求失敗都會調用那么聽上去很繞口具體概述就是如果設置了IAuthenticationFilter,則會調用OnAuthentication方法
在OnAuthentication中如果設置了filterContext的Result,則會直接跳轉到OnAuthenticationChallenge方法。
如果OnAuthentication中沒有設置filterContext的Result,則交由授權過濾器處理。如果沒有設置授權過濾器,那么
IAuthenticationFilter的OnAuthenticationChallenge方法始終會在ActionResult的ExecuteResult執行之前運行。
名稱 | 類型 | 說明 |
---|---|---|
ActionDescriptor | ActionDescriptor | 獲取或設置操作描述符。 |
Canceled | bool | 獲取或設置一個值,該值指示此ActionExecutedContext 對象已被取消。 |
Exception | Exception | 獲取或設置在操作方法的執行過程中發生的異常(如果有)。 |
ExceptionHandled | bool | 獲取或設置一個值,該值指示是否處理異常。 |
Result | ActionResult | 獲取或設置由操作方法返回的結果。 |
執行OnAuthenticationChallenge方法
我們可以通過OnAuthenticationChallenge方法來執行未授權的補充方法,比如我們這里簡單演示本地請求的方法直接返回首頁,當然這種做法很蠢,只做演示,實際過程中請不要嘗試。我們修改 CustomAuthAttribute.cs 過濾器代碼如下:
public class CustomActionAttribute : FilterAttribute, IActionFilter
{
public void OnAuthentication(AuthenticationContext filterContext)
{
var user = filterContext.HttpContext.Request.IsLocal;
if (user)
{
var Url = new UrlHelper(filterContext.RequestContext);
var url = Url.Action("Login", "Account");
filterContext.Result = new RedirectResult(url);
}
}
public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
{
var user = filterContext.HttpContext.Request.IsLocal;
if (user)
{
var Url = new UrlHelper(filterContext.RequestContext);
var url = Url.Action("Index", "Home");
filterContext.Result = new RedirectResult(url);
}
}
}
我們再來看看效果
總結
認證過濾器一般我們用的比較少,多數都會使用授權過濾器實現功能,但是認證過濾器在授權過濾器之前執行,對此我們可以用認證過濾器在授權過濾器對請求做認證,判斷此請求能否通過認證去執行授權過濾器,當然對於一些臨時的可通過的請求,我們也可以通過認證過濾器的OnAuthenticationChallenge方法讓其通過。