索引javascript
簡述html
今天咱們來寫一個控制器基類 主要作登陸用戶、權限認證、日誌記錄等工做java
項目準備web
咱們用的工具是:VS 2013 + SqlServer 2012 + IIS7.5spring
但願你們對ASP.NET MVC有一個初步的理解,理論性的東西咱們不作過多解釋,有些地方不理解也不要緊,會用就好了,用的多了,用的久了,天然就理解了。mvc
項目開始框架
不少朋友在前幾篇都遇到 根節點 的問題,我把這幾個xml先給你們貼一下ide
WebPage/Config下面三個XML工具
ComControllers.xml、IndexControllers.xmlpost
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 <description>Spring注入控制器,容器指向Service層封裝的接口</description> 4 </objects>
Controllers.xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 <description>Spring注入控制器,容器指向Service層封裝的接口</description> 4 <!--系統管理 Begin--> 5 <!--登陸控制器--> 6 <object type="WebPage.Areas.SysManage.Controllers.AccountController,WebPage" singleton="false"> 7 <property name="UserManage" ref="Service.User"/> 8 </object> 9 <!--系統管理 end--> 10 </objects>
Service/Config下面兩個XML
ComService.xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 <description>Spring注入Service,容器指向本層層封裝的接口,捨棄Dao層,減小代碼量</description> 4 </objects>
Service.xml
1 <?xml version="1.0" encoding="utf-8" ?> 2 <objects xmlns="http://www.springframework.net"> 3 <description>Spring注入Service,容器指向本層層封裝的接口,捨棄Dao層,減小代碼量</description> 4 <!--系統管理begin--> 5 <!--用戶管理--> 6 <object id="Service.User" type="Service.ServiceImp.UserManage,Service" singleton="false"> 7 </object> 8 <!--系統管理end--> 9 </objects>
變量主要用於咱們查詢分頁的時候用戶傳遞關鍵字、頁碼和分頁條數
這個用戶容器 主要是用戶後臺用戶的一些操做
1 #region 公用變量 2 /// <summary> 3 /// 查詢關鍵詞 4 /// </summary> 5 public string keywords { get; set; } 6 /// <summary> 7 /// 視圖傳遞的分頁頁碼 8 /// </summary> 9 public int page { get; set; } 10 /// <summary> 11 /// 視圖傳遞的分頁條數 12 /// </summary> 13 public int pagesize { get; set; } 14 /// <summary> 15 /// 用戶容器,公用 16 /// </summary> 17 public IUserManage UserManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.User") as IUserManage; 18 #endregion
從Sesssion中獲取用戶對象,Session過時後 經過 Cookies從新獲取用戶對象
1 #region 用戶對象 2 /// <summary> 3 /// 獲取當前用戶對象 4 /// </summary> 5 public Account CurrentUser 6 { 7 get 8 { 9 //從Session中獲取用戶對象 10 if (SessionHelper.GetSession("CurrentUser") != null) 11 { 12 return SessionHelper.GetSession("CurrentUser") as Account; 13 } 14 //Session過時 經過Cookies中的信息 從新獲取用戶對象 並存儲於Session中 15 var account = UserManage.GetAccountByCookie(); 16 SessionHelper.SetSession("CurrentUser", account); 17 return account; 18 } 19 } 20 #endregion
protected override void OnActionExecuting(ActionExecutingContext filterContext)
1 #region 登陸用戶驗證 2 //一、判斷Session對象是否存在 3 if (filterContext.HttpContext.Session == null) 4 { 5 filterContext.HttpContext.Response.Write( 6 " <script type='text/javascript'> alert('~登陸已過時,請從新登陸');window.top.location='/'; </script>"); 7 filterContext.RequestContext.HttpContext.Response.End(); 8 filterContext.Result = new EmptyResult(); 9 return; 10 } 11 //二、登陸驗證 12 if (this.CurrentUser == null) 13 { 14 filterContext.HttpContext.Response.Write( 15 " <script type='text/javascript'> alert('登陸已過時,請從新登陸'); window.top.location='/';</script>"); 16 filterContext.RequestContext.HttpContext.Response.End(); 17 filterContext.Result = new EmptyResult(); 18 return; 19 } 20 21 #endregion
1 #region 公共Get變量 2 //分頁頁碼 3 object p = filterContext.HttpContext.Request["page"]; 4 if (p == null || p.ToString() == "") { page = 1; } else { page = int.Parse(p.ToString()); } 5 6 //搜索關鍵詞 7 string search = filterContext.HttpContext.Request.QueryString["Search"]; 8 if (!string.IsNullOrEmpty(search)) { keywords = search; } 9 //顯示分頁條數 10 string size = filterContext.HttpContext.Request.QueryString["example_length"]; 11 if (!string.IsNullOrEmpty(size) && System.Text.RegularExpressions.Regex.IsMatch(size.ToString(), @"^\d+$")) { pagesize = int.Parse(size.ToString()); } else { pagesize = 10; } 12 #endregion
規則:一、根據模塊別名驗證對應模塊
二、根據模塊操做Action 驗證是否可操做按鈕
這裏咱們分爲兩個打步驟:第一,前臺按鈕沒有相應操做權限的,咱們移除前臺操做按鈕。
第二,也是爲了防止用戶繞過前臺驗證,咱們對後臺模塊以及方法進行驗證,若是用戶對相應的模塊沒有相應的操做權限(添加、修改、刪除、審覈、發佈等等,包含自定義操做類型),咱們拒絕執行。
網站的權限判斷是一個很是廣泛的需求,咱們實現這樣的需求只要從 AuthorizeAttribute 集成,重寫相關的判斷邏輯
咱們新建一個權限驗證類UserAuthorizeAttribute 繼承 AuthorizeAttribute (關於AuthorizeAttribute 點擊這裏)
public class UserAuthorizeAttribute : AuthorizeAttribute
咱們對添加一個自定義的Attribute,經過AttributeUsage的Attribute來限定Attribute 所施加的元素的類型
做爲參數的AttributeTarges的值容許經過「或」操做來進行多個值得組合,若是你沒有指定參數,那麼默認參數就是All 。
AttributeUsage除了繼承Attribute 的方法和屬性以外,還定義瞭如下三個屬性:
AllowMultiple: 讀取或者設置這個屬性,表示是否能夠對一個程序元素施加多個Attribute 。
Inherited:讀取或者設置這個屬性,表示是否施加的Attribute 能夠被派生類繼承或者重載。
ValidOn: 讀取或者設置這個屬性,指明Attribute 能夠被施加的元素的類型。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class UserAuthorizeAttribute : AuthorizeAttribute {
}
添加一些字段和屬性,而且實例化基類
1 #region 字段和屬性 2 /// <summary> 3 /// 模塊別名,可配置更改 4 /// </summary> 5 public string ModuleAlias { get; set; } 6 /// <summary> 7 /// 權限動做 8 /// </summary> 9 public string OperaAction { get; set; } 10 /// <summary> 11 /// 權限訪問控制器參數 12 /// </summary> 13 private string Sign { get; set; } 14 /// <summary> 15 /// 基類實例化 16 /// </summary> 17 public BaseController baseController = new BaseController(); 18 19 #endregion
咱們重寫 AuthorizeAttribute 的 OnAuthorization(AuthorizationContext filterContext)方法
1 /// <summary> 2 /// 權限認證 3 /// </summary> 4 public override void OnAuthorization(AuthorizationContext filterContext) 5 { 6 }
分爲四步:
一、判斷模塊是否對應
二、判斷用戶是否存在
三、調用下面的方法,驗證是否有訪問此頁面的權限,查看加操做
四、有權限訪問頁面,將此頁面的權限集合傳給頁面
1 //一、判斷模塊是否對應 2 if (string.IsNullOrEmpty(ModuleAlias)) 3 { 4 filterContext.HttpContext.Response.Write(" <script type='text/javascript'> alert('^您沒有訪問該頁面的權限!'); </script>"); 5 filterContext.RequestContext.HttpContext.Response.End(); 6 filterContext.Result = new EmptyResult(); 7 return; 8 }
1 //二、判斷用戶是否存在 2 if (baseController.CurrentUser == null) 3 { 4 filterContext.HttpContext.Response.Write(" <script type='text/javascript'> alert('^登陸已過時,請從新登陸!');window.top.location='/'; </script>"); 5 filterContext.RequestContext.HttpContext.Response.End(); 6 filterContext.Result = new EmptyResult(); 7 return; 8 }
1 //對比變量,用於權限認證 2 var alias = ModuleAlias; 3 4 #region 配置Sign調取控制器標識 5 Sign = filterContext.RequestContext.HttpContext.Request.QueryString["sign"]; 6 if (!string.IsNullOrEmpty(Sign)) 7 { 8 if (("," + ModuleAlias.ToLower()).Contains("," + Sign.ToLower())) 9 { 10 alias = Sign; 11 filterContext.Controller.ViewData["Sign"] = Sign; 12 } 13 } 14 #endregion
1 //三、調用下面的方法,驗證是否有訪問此頁面的權限,查看加操做 2 var moduleId = baseController.CurrentUser.Modules.Where(p => p.ALIAS.ToLower() == alias.ToLower()).Select(p => p.ID).FirstOrDefault(); 3 bool _blAllowed = this.IsAllowed(baseController.CurrentUser, moduleId, OperaAction); 4 if (!_blAllowed) 5 { 6 filterContext.HttpContext.Response.Write(" <script type='text/javascript'> alert('您沒有訪問當前頁面的權限!');</script>"); 7 filterContext.RequestContext.HttpContext.Response.End(); 8 filterContext.Result = new EmptyResult(); 9 return; 10 }
1 //四、有權限訪問頁面,將此頁面的權限集合傳給頁面 2 filterContext.Controller.ViewData["PermissionList"] = GetPermissByJson(baseController.CurrentUser, moduleId);
上面主要是對後臺控制器方法操做權限的驗證,有時候前臺展現了好比 添加、刪除功能,可是用戶去操做的時候後臺驗證不經過會提示用戶沒有操做權限,這樣顯得不是很友好,咱們返回個權限Json,前臺按鈕沒有這個權限的咱們就移除掉
1 /// <summary> 2 /// 獲取操做權限Json字符串,供視圖JS判斷使用 3 /// </summary> 4 string GetPermissByJson(Account account, int moduleId) 5 { 6 //操做權限 7 var _varPerListThisModule = account.Permissions.Where(p => p.MODULEID == moduleId).Select(R => new { R.PERVALUE }).ToList(); 8 return Common.JsonConverter.Serialize(_varPerListThisModule); 9 }
1 /// <summary> 2 /// 功能描述:判斷用戶是否有此模塊的操做權限 3 /// </summary> 4 bool IsAllowed(Account user, int moduleId, string action) 5 { 6 //判斷入口 7 if (user == null || user.Id <= 0 || moduleId == 0 || string.IsNullOrEmpty(action)) return false; 8 //驗證權限 9 var permission = user.Permissions.Where(p => p.MODULEID == moduleId); 10 action = action.Trim(','); 11 if (action.IndexOf(',') > 0) 12 { 13 permission = permission.Where(p => action.ToLower().Contains(p.PERVALUE.ToLower())); 14 } 15 else 16 { 17 permission = permission.Where(p => p.PERVALUE.ToLower() == action.ToLower()); 18 } 19 return permission.Any(); 20 }
模塊去重
1 /// <summary> 2 /// 模型去重,很是重要 3 /// add yuangang by 2016-05-25 4 /// </summary> 5 public class ModuleDistinct : IEqualityComparer<Domain.SYS_MODULE> 6 { 7 public bool Equals(Domain.SYS_MODULE x, Domain.SYS_MODULE y) 8 { 9 return x.ID == y.ID; 10 } 11 12 public int GetHashCode(Domain.SYS_MODULE obj) 13 { 14 return obj.ToString().GetHashCode(); 15 } 16 }
後面,咱們就用到這個基類,我先給你們看一下這個權限認證在後臺是如何使用的,加上這一句就OK了
錯誤:對不起,我犯錯誤了,好幾個項目開着,混了。你們可能都遇到了
由於我沒有添加用戶的測試數據,因此這裏一直沒發現這個錯誤,這裏很明顯是沒有注入 在Service.xml
原創文章 轉載請尊重勞動成果 http://yuangang.cnblogs.com