標籤:des style blog http color io os ar 使用
ASP.NET MVC 5.0已經發布一段時間了,適應了一段時間,準備把原來的MVC項目重構了一遍,先把基本許可權驗證這塊記錄一下。
環境:Windows 7 Professional SP1 + Microsoft Visual Studio 2013(MVC 5 + Web API 2)
修改Web.config,增加Forms驗證模式,在system.web節點中增加以下配置:
<authentication mode="Forms"> <forms loginUrl="~/login" defaultUrl="~/" protection="All" timeout="20" name="__auth" /></authentication>
【MVC View Controller 篇】
建立一個PageAuth,繼承自AuthorizeAttribute:
using System;using System.Net;using System.Web;using System.Web.Mvc;using System.Web.Security;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]public class PageAuth : AuthorizeAttribute{ protected override bool AuthorizeCore(HttpContextBase httpContext) { if (httpContext == null) { return false; } if (httpContext.User.Identity.IsAuthenticated && base.AuthorizeCore(httpContext)) { return ValidateUser(); } httpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden; return false; } public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (filterContext.HttpContext.Response.StatusCode == (int)HttpStatusCode.Forbidden) { filterContext.Result = new RedirectToRouteResult("AccessErrorPage", null); } } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { filterContext.HttpContext.Response.Redirect(FormsAuthentication.LoginUrl); } private bool ValidateUser() { //TODO: 許可權驗證 return true; }}
建一個Controller的基類PageBase,繼承自Controller:
using System.Web.Mvc;
[PageAuth]public class PageBase : Controller{}
所有View的Controller均繼承自PageBase,不再繼承自Controller。
繼承PageBase之後,所有的Controller均需登入,給允許匿名訪問的Controller(或Action)增加AllowAnonymous(以AccountController為例):
using System.Web.Mvc;
public class AccountController : PageBase{ [AllowAnonymous] public ActionResult Login() // 可匿名訪問 { ViewBag.Title = "使用者登入"; return View(); } public ActionResult Detail(int id) // 需登入訪問 { ViewBag.Title = "使用者詳情"; return View(); }}
頁面Controller的開發,基本結束,接下來就是在登入頁面(~/login)使用js提交登入資訊,用post方式提交。
提交之後,需要開發Web API的介面了。
【MVC Web API Controller 篇】
同樣,建立一個ApiAuth,繼承自ActionFilterAttribute:
using System;using System.Net;using System.Net.Http;using System.Web.Http;using System.Web.Http.Controllers;using System.Web.Http.Filters;using System.Web.Security;
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]public class ApiAuth : ActionFilterAttribute{ public override void OnActionExecuting(HttpActionContext actionContext) { try { if (actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Count > 0) // 允許匿名訪問 { base.OnActionExecuting(actionContext); return; } var cookie = actionContext.Request.Headers.GetCookies(); if (cookie == null || cookie.Count < 1) { actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden); return; } FormsAuthenticationTicket ticket = null; foreach (var perCookie in cookie[0].Cookies) { if (perCookie.Name == FormsAuthentication.FormsCookieName) { ticket = FormsAuthentication.Decrypt(perCookie.Value); break; } } if (ticket == null) { actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden); return; } // TODO: 添加其它驗證方法 base.OnActionExecuting(actionContext); } catch { actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden); } }}
建立一個ApiController的基類ApiBase,繼承自ApiController:
using System.Web.Http;
[ApiAuth]public class ApiBase : ApiController{}
所有API的Controller均繼承自ApiBase,不再繼承自ApiController。
繼承ApiBase之後,給允許匿名訪問的Controller(或Action)增加AllowAnonymous(以LoginController為例):
using System.Web.Http;using System.Web.Security;
public class LoginController : ApiBase{ [HttpPost] [AllowAnonymous] public bool Login([FromBody]LoginInfo loginInfo) { try { var cookie = FormsAuthentication.GetAuthCookie("Username", false); var ticket = FormsAuthentication.Decrypt(cookie.Value); var newTicket = new FormsAuthenticationTicket(ticket.Version, ticket.Name, ticket.IssueDate, ticket.Expiration, ticket.IsPersistent, ""); cookie.Value = FormsAuthentication.Encrypt(newTicket); DeyiContext.Response.Cookies.Add(cookie);return true; } catch { return false; } }}
【寫在最後】
網上查了很多方法,還需要時間驗證一下各個方法的合理度。
關於Web API的安全性,個人覺得,還是採用SSL的方式更加穩妥一些。
另外,網上很多寫的在Web API的許可權判斷的時候,使用的是actionContext.Request.Headers.Authorization來判斷,如下:
if (actionContext.Request.Headers.Authorization == null){ // 判斷是否允許匿名訪問}else{ var ticket = FormsAuthentication.Decrypt(actionContext.Request.Headers.Authorization.Parameter); // 後續其它驗證操作}
還沒有完成測試該方法,慢慢來吧~~~
ASP.NET MVC View 和 Web API 的基本許可權驗證