網站的權限判斷是一個非常普遍的需求,從文章ASP.NET MVC的Action Filter中我們知道實現這樣的需求只要從AuthorizeAttribute集成,重寫相關的 判斷邏輯就可以了。這裡記錄一下:
namespace TokenAcl.Web.Helper
{
public class TokenAclAuthorizeAttribute : AuthorizeAttribute
{
protected override bool AuthorizeCore (HttpContextBase httpContext)
{
bool result = false;
if (httpContext == null)
{
throw new ArgumentNullException ("httpContext");
}
string[] users = Users.Split(',');
string[] roles = Roles.Split(',');
if (! httpContext.User.Identity.IsAuthenticated)
return false;
if (roles.Length != 0)
{
List<Role> rightRoles = RightClient.GetAllRole(TakenAclMenu.SystemID, TakenAclMenu.UserID);
foreach (var role in roles)
{
if (rightRoles.Where(x => x.Code == role).Count() > 0)
{
result = true;
break;
}
}
}
if (!result)
{
httpContext.Response.StatusCode = 403;
}
return result;
}
public override void OnAuthorization (AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext);
if (filterContext.HttpContext.Response.StatusCode == 403)
{
filterContext.Result = new RedirectResult("/Admin/Dashboard");
}
}
}
}
從AuthorizeAttribute繼承過來實現了一個類TokenAclAuthorizeAttribute ,重寫了方法AuthorizeCore,使用自己開發的權限系統進行權限的驗證,如果 沒有通過認證,這表示沒有權限訪問,設置HTTP 狀態代碼為403。 這樣還是不 行,還得重寫另一個方法OnAuthorization。AuthorizeCore方法返回false,MVC 此時將返回的ActionResult是HttpUnauthorizedResult:
public class HttpUnauthorizedResult : ActionResult {
public override void ExecuteResult(ControllerContext context) {
if (context == null) {
throw new ArgumentNullException("context");
}
// 401 is the HTTP status code for unauthorized access - setting this
// will cause the active authentication module to execute its default
// unauthorized handler
context.HttpContext.Response.StatusCode = 401;
}
}
從HttpUnauthorizedResult的源碼可以看出,HttpUnauthorizedResult的執 行很簡單,就是設置當前的 HttpContext.Response的狀態碼為401,這樣就回激 活authentication module 執行它默認的 unauthorized handler,也就是跳轉 到登陸頁面的,這似乎也不符合邏輯,認證和授權應該是驗證的兩個方面。這不 符合要求,用戶已經登陸成功了,只是沒有權限而已。我這裡只是重寫 OnAuthorization方法,重定向到一個頁面而已,也可以寫一個ActionResult。