1 驗證
一般采用表單驗證完成登陸驗證,建議結合SSL使用。為限制控制器只能執(zhí)行HTTPS,使用RequireHttpsAttribute
2 授權
對賬戶的權限的控制可以通過在控制器或控制器操作上加AuthorizeAttribute 屬性。
擴展授權過濾器
擴展授權過濾器可以定義繼承自AuthorizeAttribute的類,也可以定義同時繼承自FilterAttribute, IAuthorizationFilter接口的類。
擴展AuthorizeAttribute
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter { public AuthorizeAttribute(); // 獲取或設置有權訪問控制器或操作方法的用戶角色 public string Roles { get; set; } //獲取此特性的唯一標識符。 public override object TypeId { get; } // 獲取或設置有權訪問控制器或操作方法的用戶。 public string Users { get; set; } //重寫時,提供一個入口點用于進行自定義授權檢查 // 返回結果: // 如果用戶已經過授權,則為 true;否則為 false。 // 異常: // System.ArgumentNullException: // httpContext 參數為 null。 protected virtual bool AuthorizeCore(HttpContextBase httpContext); //處理未能授權的 HTTP 請求。 protected virtual void HandleUnauthorizedRequest(AuthorizationContext filterContext); //在過程請求授權時調用。 // 異常: // System.ArgumentNullException: // filterContext 參數為 null。 public virtual void OnAuthorization(AuthorizationContext filterContext); // // 返回結果: // 對驗證狀態(tài)的引用。 // // 異常: // System.ArgumentNullException: // httpContext 參數為 null。 protected virtual HttpValidationStatus OnCacheAuthorization(HttpContextBase httpContext); }AuthorizeAttribute提供了三個可重新的虛方法AuthorizeCore,HandleUnauthorizedRequest,OnAuthorization,那么在執(zhí)行授權動作的過程中他們是如何被調用的呢?
看下源碼的OnAuthorization方法,發(fā)現在這個方法中先調用AuthorizeCore,然后調用HandleUnauthorizedRequest被調用了。
public virtual void OnAuthorization(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } //如果子操作的緩存處于活動狀態(tài),那么就拋出異常 if (OutputCacheAttribute.IsChildActionCacheActive(filterContext)) { throw new InvalidOperationException(MvcResources.AuthorizeAttribute_CannotUseWithinChildActionCache); }//判斷控制器或控制器操作是否允許匿名訪問,如果可以就return
bool skipAuthorization = filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true)|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), inherit: true); if (skipAuthorization) { return; } //進行權限驗證 if (AuthorizeCore(filterContext.HttpContext)) { HttpCachePolicyBase cachePolicy = filterContext.HttpContext.Response.Cache; cachePolicy.SetProxyMaxAge(new TimeSpan(0)); cachePolicy.AddValidationCallback(CacheValidateHandler, null /* data */); } else {//處理未通過權限驗證的情形 HandleUnauthorizedRequest(filterContext); } }綜合以上分析,擴展AuthorizeAttribute要注意:
1)在子類AuthorizeCore中,調用父類的AuthorizeCore方法
base.OnAuthorization(filterContext);
2)在子類的AuthorizeCore方法中驗證用戶的權限。
3)通過子類的構造函數傳入用戶的權限值
代碼示例如下:
public class CustomAuthorizeAttribute : AuthorizeAttribute { private UserRole role; public CustomAuthorizeAttribute(UserRole role) { this.role = role; } protected override bool AuthorizeCore(HttpContextBase httpContext) { bool ret = false; //獲得用戶信息(從本地Session或分布式緩存中獲取) var userInfo = ...... if(userInfo==null) { //信息為null,一般認為登陸超時或沒有登陸 } if(userInfo.Role == UserRole.Org) { ret = true; } else { //提示無權限 } return ret; } protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } if (filterContext.HttpContext.Request.IsAjaxRequest()) {//針對ajax請求進行處理 } else {//非aiax進行處理 //跳轉到指定頁面 string strUrl = ......; filterContext.Result = new RedirectResult(strUrl); } } public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); } } public enum UserRole { Org = 1, Vip = 2, Guest = 3 }3 安全
總的原則:
所有層或各個子系統(tǒng)各自負責好自己的安全。任何用戶數據和來自其他系統(tǒng)的數據都要經過檢驗。在滿足需求的情況下,盡量縮小賬戶的權限。減少暴露的操作數量和操作參數。關閉服務器不需要的功能。4 防范攻擊
4.1跨站腳本攻擊(XSS)
被動注入:用戶的輸入含有惡意腳本,而網站又能夠不加檢驗地接受這樣的輸入,進而保存到數據庫中。
主動注入:用戶將含有惡意腳本的內容輸入到頁面文本框中,然后在屏幕上顯示出來。
防御方法:
1)使用Razor語法輸出的內容已經被編碼,可以不做任何其他處理
例如:
<h4>@Model.Field</h4>Html.ActionLink,Html.Action等方法會將路由參數編碼輸出
2)大部分的XSS攻擊可通過對輸入內容進行編碼來阻止:Html.Encode,Html.AttributeEncode,Url.Encode
3)對Js進行編碼
使用
Ajax.JavaScriptStringEncode4)將AntiXSS庫作為默認的編碼器(不建議使用,不靈活)
ASP.NET 4.5 集成Anti-XSS Library,可以通過配置來對整個網站的輸出進行編碼。
<system.web> <httpRuntime targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder,System.Web"/> </system.web>4.2跨站請求偽造(CSRF/XSRF)
防御方法:
1)使用Html隱藏域存儲用戶令牌,令牌可以存儲在Session里或者cookie里
2)在視圖表單中使用@Html.AntiForgeryToken(),在控制器操作上添加屬性[ValidateAntiForgeryToken],注意表單一定要使用@Html.BeginForm生成
實現機制:AntiForgeryToken方法向用戶瀏覽器cookie中寫入一個加密的數據,并在表單內插入一個隱藏欄位,每次刷新頁面時隱藏欄位的值都不同,每次執(zhí)行控制器操作前,都會驗證隱藏欄位和瀏覽器cookie中的值是否相同,只有相同才允許執(zhí)行控制器操作。
使用限制:
客戶端瀏覽器不能禁用cookie只對post請求有效若有XSS漏洞,則可輕易獲取令牌對Ajax請求不能傳遞令牌,即對Ajax無效3)使用冪等的Get請求,僅使用Post請求修改數據(僅僅是一定程度上限制這種攻擊而已)
4)使用動作過濾器,驗證UrlReferrer
擴展的動作過濾器:
public class CSRFFilter:AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext.HttpContext == null) { throw new HttpException("請求無效"); } if (filterContext.HttpContext.Request.UrlReferrer == null) { throw new HttpException("請求無效"); } if (filterContext.HttpContext.Request.UrlReferrer.Host != "sit.com") { throw new HttpException("來自非法網站"); } } }4.3 cookie盜竊
cookie有兩種形式
1)會話cookie:存儲在瀏覽器內存中,瀏覽器每次請求通過Http頭進行傳遞
2)持久性cookie:存儲在硬盤上,同樣通過Http頭進行傳遞
二者的區(qū)別:會話cookie常在會話結束時失效,而持久性cookie在下一次訪問站點時仍然有效。
被竊取的原因:依賴于XSS漏洞,注入一段惡意腳本就能竊取。
防御方法:
1)在web.config對cookie進行設置
<httpCookies httpOnlyCookies="true"/>,httpOnlyCookies指定為true表達僅服務器可以訪問,瀏覽器無法訪問
2)在編寫代碼時為每個cookie單獨設置
Response.Cookies["cok"].Value = Guid.NewGuid().ToString();
Response.Cookies["cok"].HttpOnly = true;
4.4重復提交
防御方法:
1)使用bind特性,設置想要綁定的屬性來,防止這種攻擊。也可以設置不要綁定的字屬性,但優(yōu)先選擇設置要綁定的屬性。
例:
可以指定多個字段,用逗號分隔
public ActionResult TestViewData([Bind(Include = "Field,Field1,Field1")]ModelF mf) { ...... }2)使用UpdateModel或TryUpdateModel
3)使用ViewModel,明確規(guī)定View使用的數據模型
4.5開放重定向
防御方法:
使用Url.IsLocalUrl檢測是否為本地url
4.6 SQL注入攻擊
防御方法:
通過參數注入非法獲得或修改網站數據。
使用參數化查詢來防止SQL注入攻擊。
以上就是【不看后悔!原創(chuàng)(asp.net mvc與asp.net的區(qū)別)asp.net mvc和asp.net core-ASP.NET MVC知識盤點:驗證、授權與安全】的全部內容。
評論