您好,登錄后才能下訂單哦!
這篇文章給大家介紹如何淺談基于URL的權(quán)限控制ASP.NET MVC中的實現(xiàn),內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
淺談基于URL的權(quán)限控制ASP.NET MVC中的實現(xiàn)
在數(shù)據(jù)庫中新建2個表。PermissionItem表用于保存權(quán)限ID和頁面路徑的關(guān)系,一個權(quán)限ID可以有多個頁面,一般同一個權(quán)限ID下的頁面是為了實現(xiàn)同一個功能。PermissionList表用于保存用戶所具有的權(quán)限。
Code USE [UrlAuthorize] GO /****** Object: Table [dbo].[PermissionList] Script Date: 07/07/2009 00:07:10 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[PermissionList]( [ID] [int] IDENTITY(1,1) NOT NULL, [PermissionID] [int] NOT NULL, [UserID] [int] NOT NULL, CONSTRAINT [PK_PermissionList] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[PermissionList] ON INSERT [dbo].[PermissionList] ([ID], [PermissionID], [UserID]) VALUES (1, 2, 1) INSERT [dbo].[PermissionList] ([ID], [PermissionID], [UserID]) VALUES (2, 3, 1) SET IDENTITY_INSERT [dbo].[PermissionList] OFF /****** Object: Table [dbo].[PermissionItem] Script Date: 07/07/2009 00:07:10 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_PADDING ON GO CREATE TABLE [dbo].[PermissionItem]( [ID] [int] IDENTITY(1,1) NOT NULL, [PermissionID] [int] NOT NULL, [Name] [nvarchar](50) NOT NULL, [Route] [varchar](100) NOT NULL, CONSTRAINT [PK_PermissionItem] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET ANSI_PADDING OFF GO SET IDENTITY_INSERT [dbo].[PermissionItem] ON INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (1, 1, N'測試頁1', N'/Test/Page1') INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (2, 2, N'測試頁2', N'/Test/Page2') INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (3, 3, N'測試頁3', N'/Test/Page3') INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (5, 1, N'測試頁4', N'/Test/Page4') INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (6, 2, N'測試頁5', N'/Test/Page5') SET IDENTITY_INSERT [dbo].[PermissionItem] OFF
數(shù)據(jù)庫中的示例表示Page1和Page4同屬于權(quán)限1,Page2和Page5同屬于權(quán)限2,Page3屬于權(quán)限3。用戶ID為1的用戶具有權(quán)限2和3。
在ASP.NET MVC項目中新建一個AccountHelper類,這是一個輔助類。GetPermissionItems方法用于獲取權(quán)限ID和頁面路徑的對應(yīng)關(guān)系。這是全局的,并且每個用戶在訪問頁面時都會用到這些信息,所以存入Cache中。數(shù)據(jù)庫的相關(guān)操作這里使用的是ADO.NET Entity Framework。
1/**//// <summary> 2/// 獲取權(quán)限項 3/// </summary> 4/// <returns>權(quán)限項列表</returns> 5public static List<PermissionItem> GetPermissionItems() 6{ 7 // 如果緩存中已經(jīng)存在權(quán)限列表信息,則直接從緩存中讀取。 8 if (HttpContext.Current.Cache["PermissionItems"] == null) 9 { 10 // 如果緩存中沒有權(quán)限列表信息,則從數(shù)據(jù)庫獲取并寫入緩存 11 UrlAuthorizeEntities db = new UrlAuthorizeEntities(); 12 var items = db.PermissionItem.Where(c => c.PermissionID > 0).ToList(); 13 HttpContext.Current.Cache["PermissionItems"] = items; 14 } 15 16 // 這個緩存中保存了所有需要進(jìn)行權(quán)限控制的頁面所對應(yīng)的權(quán)限ID 17 return (List<PermissionItem>)HttpContext.Current.Cache["PermissionItems"]; 18} 19
GetUserPermission方法是將用戶所具有的權(quán)限ID保存到一個一維Int32數(shù)組中。這個信息每個用戶是不同的,但是會經(jīng)常使用到,所以存入Session。
1/**//// <summary> 2/// 獲取用戶權(quán)限 3/// </summary> 4/// <param name="userID">用戶ID</param> 5/// <returns>用戶權(quán)限數(shù)組</returns> 6public static Int32[] GetUserPermission(int userID) 7{ 8 // 如果緩存中已經(jīng)存在權(quán)限列表信息,則直接從緩存中讀取。 9 if (HttpContext.Current.Session["Permission"] == null) 10 { 11 // 從數(shù)據(jù)庫獲取用戶權(quán)限并將權(quán)限ID放到int數(shù)組并存入Session 12 UrlAuthorizeEntities db = new UrlAuthorizeEntities(); 13 var permissions = db.PermissionList.Where(c => c.UserID == userID).Select(c=>c.PermissionID).ToArray(); 14 HttpContext.Current.Session["Permission"] = permissions; 15 } 16 return (Int32[])HttpContext.Current.Session["Permission"]; 17} 18
再新建一個UrlAuthorizeAttribute類,繼承自AuthorizeAttribute,這是一個Filter。我們重寫它的OnAuthorization方法,以在ASP.NET頁生命周期身份驗證階段執(zhí)行它。
1/**//// <summary> 2/// 重寫OnAuthorization 3/// </summary> 4/// <param name="filterContext"></param> 5public override void OnAuthorization(AuthorizationContext filterContext) 6{ 7 // 獲取權(quán)限項列表 8 List<PermissionItem> pItems = AccountHelper.GetPermissionItems(); 9 10 // 獲取當(dāng)前訪問頁面對應(yīng)的權(quán)限ID。如果item為空則表示當(dāng)前頁面沒有權(quán)限控制信息,不需要進(jìn)行權(quán)限控制 11 var item = pItems.FirstOrDefault(c => c.Route == filterContext.HttpContext.Request.Path); 12 13 if (item != null) 14 { 15 if (Array.IndexOf<Int32>(AccountHelper.GetUserPermission(int.Parse(filterContext.HttpContext.Session["UserID"].ToString())), item.PermissionID) == -1) 16 { 17 // 提示權(quán)限不夠,也可以跳轉(zhuǎn)到其他頁面 18 filterContext.HttpContext.Response.Write("沒有權(quán)限訪問該頁面"); 19 filterContext.HttpContext.Response.End(); 20 } 21 } 22 else 23 { 24 // 如果權(quán)限項列表中不存在當(dāng)前頁面對應(yīng)的權(quán)限ID則所有用戶都不允許訪問,直接提示無權(quán)訪問。***注1*** 25 filterContext.HttpContext.Response.Write("沒有權(quán)限訪問該頁面"); 26 filterContext.HttpContext.Response.End(); 27 } 28} 29
至此,主要的工作都已經(jīng)完成了的。接下來我們只需要在需要進(jìn)行基于URL權(quán)限控制的Action或Controller前加上[UrlAuthorize],這些Action或Controller中的所有Actions就會自動被UrlAuthorize這個Filter進(jìn)行處理。如果某一個Action被標(biāo)上了[UrlAuthorize],而數(shù)據(jù)庫中又不存在該頁面對應(yīng)的權(quán)限ID,那么根據(jù)示例的代碼,所有用戶都將無法訪問這個頁面,如果需要更改這個設(shè)置,可以修改上面“注1”下面的2行代碼。
關(guān)于如何淺談基于URL的權(quán)限控制ASP.NET MVC中的實現(xiàn)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。