本示例演示了在ASP.NET MVC中进行基于URL的权限控制,由于是基于URL进行控制的,所以只能精确到页。这种权限控制的优点是可以在已有的项目上改动极少的代码来增加权限控制功能,和项目本身的耦合度低,并且实现起来也比较简单。缺点是权限控制不够精确,不能具体到某一具体的按钮或者某一功能。

在数据库中新建2个表。PermissionItem表用于保存权限ID和页面路径的关系,一个权限ID可以有多个页面,一般同一个权限ID下的页面是为了实现同一个功能。PermissionList表用于保存用户所具有的权限。

  1. USE [UrlAuthorize]
  2. GO
  3. /****** Object:  Table [dbo].[PermissionList]    Script Date: 07/07/2009 00:07:10 ******/
  4. SET ANSI_NULLS ON
  5. GO
  6. SET QUOTED_IDENTIFIER ON
  7. GO
  8. CREATE TABLE [dbo].[PermissionList](
  9.     [ID] [int] IDENTITY(1,1) NOT NULL,
  10.     [PermissionID] [int] NOT NULL,
  11.     [UserID] [int] NOT NULL,
  12.  CONSTRAINT [PK_PermissionList] PRIMARY KEY CLUSTERED 
  13. (
  14.     [ID] ASC
  15. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  16. ) ON [PRIMARY]
  17. GO
  18. SET IDENTITY_INSERT [dbo].[PermissionList] ON
  19. INSERT [dbo].[PermissionList] ([ID], [PermissionID], [UserID]) VALUES (1, 2, 1)
  20. INSERT [dbo].[PermissionList] ([ID], [PermissionID], [UserID]) VALUES (2, 3, 1)
  21. SET IDENTITY_INSERT [dbo].[PermissionList] OFF
  22. /****** Object:  Table [dbo].[PermissionItem]    Script Date: 07/07/2009 00:07:10 ******/
  23. SET ANSI_NULLS ON
  24. GO
  25. SET QUOTED_IDENTIFIER ON
  26. GO
  27. SET ANSI_PADDING ON
  28. GO
  29. CREATE TABLE [dbo].[PermissionItem](
  30.     [ID] [int] IDENTITY(1,1) NOT NULL,
  31.     [PermissionID] [int] NOT NULL,
  32.     [Name] [nvarchar](50) NOT NULL,
  33.     [Route] [varchar](100) NOT NULL,
  34.  CONSTRAINT [PK_PermissionItem] PRIMARY KEY CLUSTERED 
  35. (
  36.     [ID] ASC
  37. )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
  38. ) ON [PRIMARY]
  39. GO
  40. SET ANSI_PADDING OFF
  41. GO
  42. SET IDENTITY_INSERT [dbo].[PermissionItem] ON
  43. INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (1, 1, N'测试页1', N'/Test/Page1')
  44. INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (2, 2, N'测试页2', N'/Test/Page2')
  45. INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (3, 3, N'测试页3', N'/Test/Page3')
  46. INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (5, 1, N'测试页4', N'/Test/Page4')
  47. INSERT [dbo].[PermissionItem] ([ID], [PermissionID], [Name], [Route]) VALUES (6, 2, N'测试页5', N'/Test/Page5')
  48. SET IDENTITY_INSERT [dbo].[PermissionItem] OFF

数据库中的示例表示Page1和Page4同属于权限1,Page2和Page5同属于权限2,Page3属于权限3。用户ID为1的用户具有权限2和3。

在ASP.NET MVC项目中新建一个AccountHelper类,这是一个辅助类。GetPermissionItems方法用于获取权限ID和页面路径的对应关系。这是全局的,并且每个用户在访问页面时都会用到这些信息,所以存入Cache中。数据库的相关操作这里使用的是ADO.NET Entity Framework。

  1.  
  2.  1/// <summary>
  3.  2/// 获取权限项
  4.  3/// </summary>
  5.  4/// <returns>权限项列表</returns>
  6.  5public static List<PermissionItem> GetPermissionItems()
  7.  6{
  8.  7     // 如果缓存中已经存在权限列表信息,则直接从缓存中读取。
  9.  8      if (HttpContext.Current.Cache["PermissionItems"] == null)
  10.  9     {
  11. 10          // 如果缓存中没有权限列表信息,则从数据库获取并写入缓存
  12. 11           UrlAuthorizeEntities db = new UrlAuthorizeEntities();
  13. 12          var items = db.PermissionItem.Where(=> c.PermissionID > 0).ToList();
  14. 13          HttpContext.Current.Cache["PermissionItems"] = items;
  15. 14     }
  16. 15
  17. 16     // 这个缓存中保存了所有需要进行权限控制的页面所对应的权限ID
  18. 17     return (List<PermissionItem>)HttpContext.Current.Cache["PermissionItems"];
  19. 18}
  20. 19

GetUserPermission方法是将用户所具有的权限ID保存到一个一维Int32数组中。这个信息每个用户是不同的,但是会经常使用到,所以存入Session。

  1.  
  2.  1/// <summary>
  3.  2/// 获取用户权限
  4.  3/// </summary>
  5.  4/// <param name="userID">用户ID</param>
  6.  5/// <returns>用户权限数组</returns>
  7.  6public static Int32[] GetUserPermission(int userID)
  8.  7{
  9.  8    // 如果缓存中已经存在权限列表信息,则直接从缓存中读取。
  10.  9    if (HttpContext.Current.Session["Permission"] == null)
  11. 10    {
  12. 11        // 从数据库获取用户权限并将权限ID放到int数组并存入Session
  13. 12        UrlAuthorizeEntities db = new UrlAuthorizeEntities();
  14. 13        var permissions = db.PermissionList.Where(=> c.UserID == userID).Select(c=>c.PermissionID).ToArray();
  15. 14        HttpContext.Current.Session["Permission"] = permissions;
  16. 15    }
  17. 16    return (Int32[])HttpContext.Current.Session["Permission"];
  18. 17}
  19. 18

再新建一个UrlAuthorizeAttribute类,继承自AuthorizeAttribute,这是一个Filter。我们重写它的OnAuthorization方法,以在ASP.NET页生命周期身份验证阶段执行它。

  1.  
  2.  1/// <summary>
  3.  2/// 重写OnAuthorization
  4.  3/// </summary>
  5.  4/// <param name="filterContext"></param>
  6.  5public override void OnAuthorization(AuthorizationContext filterContext)
  7.  6{
  8.  7    // 获取权限项列表
  9.  8    List<PermissionItem> pItems = AccountHelper.GetPermissionItems();
  10.  9
  11. 10    // 获取当前访问页面对应的权限ID。如果item为空则表示当前页面没有权限控制信息,不需要进行权限控制
  12. 11    var item = pItems.FirstOrDefault(=> c.Route == filterContext.HttpContext.Request.Path);
  13. 12
  14. 13    if (item != null)
  15. 14    {
  16. 15        if (Array.IndexOf<Int32>(AccountHelper.GetUserPermission(int.Parse(filterContext.HttpContext.Session["UserID"].ToString())), item.PermissionID) == -1)
  17. 16        {
  18. 17            // 提示权限不够,也可以跳转到其他页面
  19. 18            filterContext.HttpContext.Response.Write("没有权限访问该页面");
  20. 19            filterContext.HttpContext.Response.End();
  21. 20        }
  22. 21    }
  23. 22    else
  24. 23    {
  25. 24        // 如果权限项列表中不存在当前页面对应的权限ID则所有用户都不允许访问,直接提示无权访问。***注1***
  26. 25        filterContext.HttpContext.Response.Write("没有权限访问该页面");
  27. 26        filterContext.HttpContext.Response.End();
  28. 27    }
  29. 28}
  30. 29

至此,主要的工作都已经完成了的。接下来我们只需要在需要进行权限控制的Action或Controller前加上[UrlAuthorize],这些Action或Controller中的所有Actions就会自动被UrlAuthorize这个Filter进行处理。如果某一个Action被标上了[UrlAuthorize],而数据库中又不存在该页面对应的权限ID,那么根据示例的代码,所有用户都将无法访问这个页面,如果需要更改这个设置,可以修改上面“注1”下面的2行代码。

示例代码下载

在ASP.NET MVC中实现基于URL的权限控制的更多相关文章

  1. 在ASP.NET MVC 中获取当前URL、controller、action 、参数

    URL的获取很简单,ASP.NET通用:[1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟目录名 ...

  2. springboot整合security实现基于url的权限控制

    权限控制基本上是任何一个web项目都要有的,为此spring为我们提供security模块来实现权限控制,网上找了很多资料,但是提供的demo代码都不能完全满足我的需求,因此自己整理了一版. 在上代码 ...

  3. 基于 URL 的权限控制

    先不用框架,自己实现一下 数据库 /* SQLyog v10.2 MySQL - 5.1.72-community : Database - shiro *********************** ...

  4. 在ASP.NET MVC 中获取当前URL、controller、action

    一.URL的获取很简单,ASP.NET通用: [1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟 ...

  5. asp.net MVC中获取当前URL/Controller/Action

    一.获取URL(ASP.NET通用): [1]获取完整url(协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取虚拟目录名+页面 ...

  6. 在ASP.NET MVC 中获取当前URL、controller、action(转)

    URL的获取很简单,ASP.NET通用: [1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟目录 ...

  7. 如何在ASP.NET MVC 中获取当前URL、controller、action

    一.URL的获取很简单,ASP.NET通用: [1]获取 完整url (协议名+域名+虚拟目录名+文件名+参数) string url=Request.Url.ToString(); [2]获取 虚拟 ...

  8. 在ASP.NET MVC中使用Knockout实践04,控制View Model的json格式内容

    通常,需要把View Model转换成json格式传给服务端.但在很多情况下,View Model既会包含字段,还会包含方法,我们只希望把字段相关的键值对传给服务端. 先把上一篇的Product转换成 ...

  9. MVC中AuthorizeAttribute用法并实现权限控制

    1.创建一个类(用来检查用户是否登录和用户权限)代码如下: public class AuthorizeFilterAttribute: AuthorizeAttribute    { //Autho ...

随机推荐

  1. OpenJudge 2786 Pell数列

    1.链接地址: http://bailian.openjudge.cn/practice/2786 2.题目: 总Time Limit: 3000ms Memory Limit: 65536kB De ...

  2. 安装FreeMind

    Freemind 1.0.0 官方正式版下载地址:http://dl.pconline.com.cn/html_2/1/131/id=46751&pn=0.html 软件介绍: Freemin ...

  3. Linux+svn无法显示日志

    自己在linux中配置了一个svn服务器,但是客户端在浏览日志的时候报错.提示不能连接到服务器,是否离线查看... 谷歌了一下,是因为svnserve.conf中配置了anon-access = re ...

  4. Oracle笔记1

    ORACLE: 目前分为12C(cloud云)和11G(grid网格)版本 --数据库基本概念 data--数据 database--数据库 DBMS--数据库管理系统 RDBMS--关系型数据库管理 ...

  5. 初涉GitHub

    安装 访问https://help.github.com/articles/set-up-git/,选择对应OS平台.有文档参考,我的是OpenSuse. 在console中下载安装http://ww ...

  6. margin系列之百分比

    本系列摘自  px; height: 600px; } #demo p{ margin: 10% 5%; } HTML: <div id="demo"> <p&g ...

  7. uCGUI窗口重绘代码分析

    一.概述 µC/GUI的窗口重绘是学习者理解窗口工作原理和应用窗口操作的重点.µC/GUI的窗口重绘引入了回调机制,回调机制可以实现图形系统调用用户的代码,由于图形系统使用了剪切算法,使得屏幕重绘的效 ...

  8. [Linux/Ubuntu] vi/vim 使用方法讲解(转载)

    转自:http://www.cnblogs.com/emanlee/archive/2011/11/10/2243930.html vi/vim 基本使用方法 vi编辑器是所有Unix及Linux系统 ...

  9. Git权威指南 读笔(4)

    第12章 改变历史: $ git commit --amend -m "Remove hello.h, which is useless." 修改提交说明 $ git log -- ...

  10. VS Extension: Open Web Address with Visual Studio Browser

    使用VS 打开链接 using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; ... public ...