65.9K
CodeProject 正在变化。 阅读更多。
Home

酷权限控制系统 第1部分 -- ASP.NET MVC

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.99/5 (80投票s)

2016年1月27日

Ms-PL

18分钟阅读

viewsIcon

203845

downloadIcon

3510

独立的权限控制,单点登录解决方案

引言

众所周知,权限控制是一种普遍且基础的机制。人们会被分配到不同的访问角色,其中一些人可以根据他们的角色维护敏感信息,而另一些人则不能。在计算机世界也是如此。例如,著名的PC操作系统Microsoft Window就有一个用户管理系统,不同的用户登录拥有不同的访问权限,操作不同的文件或文件夹,操作系统管理员可以创建具有不同权限的不同用户帐户。例如,Ricky是一名管理员,Jenny是一名访客,他们都通过登录名和密码登录系统。Ricky可以控制计算机上的一切,而Jenny除了查看权限外没有任何权限。为了解决复杂的情况,我们需要开发一个系统来帮助我们。显而易见,权限控制是其他系统之上的一个基础机制。

背景

既然权限控制是一个基础机制,它应该已经被实现了。很多人会问“你为什么在这里讨论?你知道在浪费我们的时间吗?”。我想说“不”。根据多年的经验,我参与开发了许多项目,其中大部分都有访问权限控制,除了小型系统。以人力资源管理系统为例。人力资源管理系统包含大量敏感信息,并且有许多不同的模块,例如ESS(员工自助服务)、请假模块、薪资模块、考勤模块等。所有这些模块都应该有访问权限控制。过去,我们曾为不同的模块创建不同的访问权限控制系统。这意味着如果一个名叫Jenny的用户要为这个人力资源管理系统拥有五个以上的帐户。这不仅让Jenny难以记住这些帐户,而且难以维护。此外,大多数现有系统未能涵盖所有实际情况。例如,Jenny是一名销售经理,她只能访问她团队下的人员,而不能访问其他团队的同事。所以今天,我将向遇到和我一样问题的人介绍酷权限控制。

我设计的酷权限控制系统用于集中化功能和用户操作,并解决不同的访问级别问题。它看起来像单点登录系统,并且基于ASP.NET MVC,但它不仅仅局限于Web应用程序,因为我将解决方案拆分成了多个层,UI(用户界面MVC)、BL(业务层)和DAL(数据访问层)。很容易将UI从MVC替换为桌面应用程序(WPF),并将BL与DAL合并到WCF中。如果你是一名MVC开发人员,酷权限控制不仅为你提供单点登录解决方案,还为你提供了一个原型项目框架。

特点

  1. 解决正常的访问控制问题(即用户和用户角色、功能和功能类型)
  2. 解决用户在不同组织中具有不同访问级别的问题
  3. 提供强大的审计日志、跟踪日志和异常日志
  4. 轻松快速地创建具有权限控制和自动生成菜单的原型
  5. 支持多语言

外观

首先,我截取了一些应用程序屏幕截图,以提高学习专注度。

图 4.1 (登录屏幕)

图 4.2 (功能管理)

图 4.3 (编辑登录用户)

图 4.4 (系统审计日志管理)

是不是很酷?感谢Bootstrap!它是一个漂亮的UI工具包,可以为开发人员节省大量工作!从现在开始,我们将深入分析现实生活中所有访问控制的场景。

场景

5.1 场景 1

系统有许多功能,每个功能有许多功能类型(即insertupdateimportexport等),可以分配给不同的功能,这意味着功能A有一个import方法,功能B也有一个import方法。所以功能和功能类型之间的关系是多对多的。以下图示很容易描述实体关系。

图 5.1.1 功能与功能类型关系

注意:在实际情况中,功能结构可能非常复杂。我使用了“000100010001”格式来分隔功能级别。例如,功能路径“0001”表示HR模块,其中有许多功能。例如,“00010001”表示员工信息管理,“00010002”表示薪资信息管理,然后“000100020001”和“000100020002”分别表示薪资信息维护和薪资审查。

图 5.1.2 功能结构 (HR模块)

基于“000100020002”格式,我们直接通过递归知道名为“HR模块”的顶层菜单。每个级别有9999个功能。当然,我们可以通过增加数字长度来增加每个级别的功能数量,如果我们使用“000010000200002”格式而不是“000100020002”,那么我们可以存储每个级别的99999个功能。下图显示了菜单的样子

图 5.1.3 菜单 (HR模块)

5.2 场景 2

登录用户可以被分配到特定的功能或特定的角色。如果一个登录用户被分配到多个角色,那么该用户可以访问那些角色中定义的所有功能。这意味着角色A对功能A有访问权限,角色B对功能B有访问权限,如果角色A和角色B都被分配给一个名为“Ricky”的用户,那么Ricky可以访问功能A和功能B。下图是用户-角色实体关系。

图 5.2.1 用户-角色关系

5.3 场景 3

每个用户可以被分配到一个或多个特定组织,如果这样做,他/她将只能被允许访问其下属的信息。为了解决这些问题,我们应该创建一个名为“组织详情”的新实体,它帮助系统存储组织分配的权限。这可能不容易理解。以一个容易理解的实际案例为例。

  1. 一个名叫“Angus”的用户,他的职位是项目经理和销售助理经理。

    假设以下设置。

    对“功能管理”功能拥有只读权限。

    对“登录用户管理”功能拥有项目经理级别的完全访问权限。

    对“登录用户管理”功能拥有销售助理经理级别的只读权限。

  2. 一个名叫“Wells”的用户是项目团队的成员。
  3. 一个名叫“Michael”的用户是销售团队的成员。

预期结果

当Angus登录系统时,他可以访问两个功能,一个是“功能管理”,另一个是“登录用户管理”。根据设置,Angus对“功能管理”只有搜索和查看权限。同时,对于“登录用户管理”功能,Angus可以插入/更新/删除项目团队成员的用户记录,但是,他不能插入/更新/删除销售团队成员的用户记录,只能查看和搜索。

根据以上案例,我们应该设置两个组织详情设置,一个是“ReadOnly”,另一个是“Login User Full Access”。以下屏幕显示了组织详情设置。

图 5.3.1 功能详情设置 -- 只读

说明:名为“ReadOnly”的组织详情对功能管理拥有“Search”和“View”权限。

说明:“ReadOnly”组织详情仅对登录用户管理拥有“Search”和“View”权限。

图 5.3.2 功能详情设置 -- 登录用户完全权限

说明:名为“Login User Full Privilege”的组织详情对登录用户管理拥有完全访问权限。

图 5.3.3 登录用户设置

说明:一个名为“Angus”的登录用户被分配到两个组织设置

项目团队 – 登录用户完全权限

销售团队 – 只读

图 5.3.4.1 组织结构

图 5.3.4.2 组织结构设置

说明:之前的组织设置使用“000100010001”格式来表示组织结构。

图 5.3.5 登录用户列表 (所有用户)

Angus登录后,他会看到以下屏幕。

图 5.3.6 功能管理屏幕

说明:先前屏幕中的所有编辑/删除按钮都已变灰。因为“Angus”对该功能只有查看/搜索权限。

图 5.3.7 登录用户管理屏幕

说明:如上屏幕所示,对于登录名为Angus或Michael的用户,编辑和删除按钮都已变灰,因为Angus无法维护销售团队成员下的用户和他自己,但可以维护项目团队下的用户。

下图显示了该场景的ER图

图 5.3.6 场景实体关系

设置

为了满足MSSQL和MYSQL数据库开发人员的需求,我发布了两个版本的项目。如果您默认使用MSSQL,请下载“CoolAccessControl.Community.MYSQL.zip”,否则,请下载“CoolAccessControl.Community.MSSQL.zip”。我列出了我的开发环境供您参考。如果您的本地开发环境低于我的,我建议您先升级环境,这样您才能成功运行程序。如果您的本地版本与我的开发环境相同或更高,则没有兼容性问题,我对此表示信任。

  1. Microsoft Visual Studio 2013
  2. .NET Framework 4.5.1
  3. MSSQL Server 2012 或 MYSQL 5.6.26
  4. MVC 5.2.3
  5. Entity Framework 6.0

强制步骤:打开解决方案后,请右键单击解决方案并选择“启用NuGet程序包还原”。

图 6.0.1 启用NuGet程序包还原

6.1 编辑 WEB.CONFIG 文件

6.1.1 对于MYSQL用户

图 6.1.1 web.config (MySql 版本)

请注意appSettings节点,根据mysql服务器设置更改DBSource/DBName/DBPort/LoginName/LoginPWD的值。

属性 描述
DBSource 服务器主机的IP地址
DBName 数据库名称
DBPort 服务器TCP/IP端口
LoginName DB用户名
LoginPWD DB用户密码
IsDebug 如果设置为true,所有异常将显示在页面上,反之亦然

6.1.2 对于MSSQL用户

图 6.1.2 web.config (MSSql 版本)

与mysql用户相同,根据mssql服务器设置更改DBSource/DBName/LoginName/LoginPWD的值,但DBPort除外。在mssql服务器中,端口号可以在服务器名称或服务器IP地址后用逗号指定。例如

WELLSCHEUNG\MSSQLSERVER2012,49287 49287是端口。

属性 描述
DBSource 服务器主机的IP地址

带端口格式:服务器名称或IP地址,端口

DBName 数据库名称
LoginName DB用户名
LoginPWD DB用户密码
IsDebug 如果设置为true,任何异常都会显示在页面上,反之亦然。

6.1.3 启用或禁用数据库初始化程序

这是实体框架代码优先设计模式的功能。这是我听说过的最有用的功能。当您执行项目时,如果数据库实例不存在于服务器中且标志已启用,实体框架将帮助您初始化数据库架构。更多信息,请参阅MSDN。如果您不想自动初始化数据库并覆盖您的数据库,可以将上下文元素中的属性“disableDatabaseInitialization”设置为true

图 6.1.3 disableDatabaseInitialization 标志

或者,您可以通过SQL脚本或数据库备份来初始化数据库。我准备了SQL脚本供mysql用户执行,并准备了数据库备份供mssql用户恢复。

6.2 编辑 Log4Net.config 文件

我们使用log4net来帮助我们记录跟踪信息和错误信息。关于如何使用log4net,我认为你们大多数人都比我更有经验,所以我不想花太多时间重复。我只指定系统中所有功能默认启用跟踪日志(即包括输入和输出信息)。这是跟踪错误的简单方法,即使我们在现场支持时无法运行Visual Studio调试。

关闭或更改您想捕获的另一种类型的信息非常容易。log4net中预设了七个级别类型。

以下级别按优先级递增的顺序定义

  • ALL
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • 致命错误

您可以将level属性的值替换为log4net.config中的上述级别。

图 6.2.1 Log4Net.config
SysLog:记录系统所有信息
ErrorLog:仅记录系统异常

如前所述,之前的设置将影响系统中的所有功能。如果您想单独禁用记录器,可以将函数标记为“[UnTracerAction]”函数,则该函数不会被跟踪。

图 6.2.2 UnTracerAction 函数

如果您只想验证函数是否被执行,而不需要详细信息,可以将函数标记为`"[TracerActionWithDetails(EnableTracer=false)]"`函数。

图 6.2.3 [TracerActionWithDetails(EnableTracer=false)] 函数

以下截图演示了之前不同设置的结果。

图 6.2.4 无详细信息的跟踪操作日志

图 6.2.5 有详细信息的跟踪操作日志

完成以上设置后,系统即可使用。在Visual Studio中按“F5”并仔细检查是否有编译错误。如果出现任何错误,您可以将错误发送给我检查,或自行在Google上搜索解决方案。

在下一节中,我将介绍系统中的功能。包括创建功能类型、创建功能、创建登录用户、创建角色、创建组织、创建访问级别、将功能分配给特定登录用户等。

如何使用

7.1 系统设置

  1. 在主菜单“访问管理”中,点击子菜单“系统信息管理”。

    7.1.1

  2. 根据您的需求更改值。

    7.1.2

描述
会话超时(秒) 默认值为10分钟=600秒。酷权限控制有一个会话管理机制,它依赖于ASP.NET的会话管理机制,也就是说,如果您将值更改为20分钟或20分钟以上,任何会话在没有用户操作的情况下只能保持20分钟。因为ASP.NET中的空闲时间默认为20分钟。如果您想设置会话超时时间超过20分钟,您必须将ASP.NET的会话超时时间设置为大于酷权限控制系统的会话超时时间。关于如何更改ASP.NET中的会话超时时间,请参阅此链接。我曾将ASP.NET会话超时时间延长到60分钟。

7.1.2.1

页面大小 每个列表页面的页面大小。
分页条中显示的最大页码数 分页条中显示的最大页码数

7.1.2.2

日期格式 默认格式:yyyy-MM-dd。例如:2016-01-21
时间格式 默认格式:HH-mm-ss。例如:22:10:05
密码策略 它包含许多规则。我认为它涵盖了正常使用,我不想花很多时间在这里解释每个规则。我相信你们都有能力理解这些规则。

7.2 维护功能类型

酷权限控制允许用户直接创建功能类型。查看、搜索、创建、编辑、删除、导出、导入、预览和处理是最常见的功能类型。为避免重复劳动,系统将在数据库初始化后添加这些功能类型。

  1. 创建功能类型

    1. 在“功能类型管理”页面的左下方点击“创建功能类型”按钮。

      7.2.1.1
    2. 输入“功能类型”。例如:“Generate”。

      7.2.1.2
    3. 点击“保存”按钮。

  2. 删除功能类型

    点击您想要删除记录的“删除”按钮。

  3. 编辑功能类型

    1. 点击“编辑

      7.2.1.3.1
    2. 更改“功能类型”。

    3. 点击“保存”按钮。

7.3 维护功能

如第5节所述,酷权限控制使用“000100010001”格式分隔功能。理论上,系统支持无限数量的功能级别,每个功能级别支持9999个功能。

  1. 创建功能

    1. 在“功能管理”页面的左下方点击“创建功能”按钮。

      7.3.1.1
    2. 输入“功能键”和“功能路径”,选择属于该功能“功能类型”。

      7.3.1.2
    3. 点击“保存”按钮。

      7.3.1.3
  2. 删除功能

    点击您想要删除记录的“删除”按钮。

  3. 编辑功能

    1. 点击您想要编辑的记录的“编辑”按钮。

    2. 更改值并点击“保存”按钮。

7.4 维护角色

  1. 创建角色

    1. 在“角色管理”页面的左下方点击“创建用户角色”按钮。

    2. 输入“角色名称”,例如:Admin

    3. 为新角色分配带有“功能类型”的“功能”。

      7.4.1.3
    4. 点击“保存”按钮。

  2. 删除角色

    点击您想要删除记录的“删除”按钮。

  3. 编辑角色

    步骤与上述部分相同。

7.5 维护组织

  1. 创建组织

    1. 在“组织管理”页面的左下方点击“创建组织”按钮。

    2. 输入“组织键”,例如:CEO

    3. 输入“组织路径”,例如:0001

  2. 删除组织(省略)

  3. 编辑组织(省略)

7.6 维护组织详情

  1. 创建组织详情

    1. 在“组织详情管理”页面的左下方点击“创建组织详情”按钮。

    2. 输入“组织详情键”。

    3. 选择“组织详情类型”。

      有两种类型的组织详情。一种是“特定功能”,另一种是“角色设置”。您可以为其分配特定功能,或设置为角色设置。

      图 7.6.1 特定功能
      图 7.6.2 角色设置
    4. 点击“保存”按钮。

  2. 删除组织详情(省略)

  3. 编辑组织详情(省略)

7.7 维护登录用户

  1. 创建登录用户

    1. 在“登录用户管理”页面的左下方点击“创建登录用户”按钮。

      7.7.1.1
    2. 输入必填字段。例如:登录名/密码/确认密码/状态。

    3. 选择“登录用户类型”。

      1. 特定功能:将特定功能分配给用户。

      2. 角色设置:将预设角色分配给用户。

      3. 组织设置:将组织单位与相关的组织详情分配给用户。

        7.7.1.3
      4. 点击“保存”按钮。

  2. 删除登录用户(省略)

  3. 编辑登录用户(省略)

7.8 系统审计日志管理

在此功能中,您可以检索系统记录的所有事件,并通过选择标准筛选您想要的内容。此外,您可以将日志导出为Excel文件以供检查。

7.8

7.9 授权历史管理

7.9

7.10 多语言

如第一部分所述,酷权限控制基于多语言设计模式。目前,系统中支持三种语言:英语、简体中文和繁体中文。我们可以通过添加资源文件来扩展语言包。我希望您能帮助我添加更多语言包到系统中。您可以将您的资源文件发送到我的电子邮件(wells-z@hotmail.comwellscheung@gmail.com),我将整合所有资源文件并将其注入系统中。下一部分将介绍如何创建本地化版本的资源文件。

7.10.1 创建本地化版本的资源文件

  1. 打开名为“CoolAccessControlLangPack”的项目。

    7.10.1.1

    我们需要创建三类资源文件。它们是FunctionRes.resxlblCommon.resxMsgRes.resx

  2. 解决方案资源管理器中,右键单击项目,指向“添加”,然后单击“新建项”。
    在“添加新项”对话框中,选择“资源文件”并将文件命名为FunctionRes.de-de.resx。文件名表示语言(德语)和国家(德国)。
    文件名格式
    <language-country><base file name>.<language-country>.resx
    如果您不知道国家代码和语言代码,请访问以下链接
    http://www.csharp-examples.net/culture-names/
    我们必须为每种语言和每个国家创建三个文件。
    例如:

    • FunctionRes.de-de.resx

    • lblCommon.de-de.resx

    • MsgRes.de-de.resx

      7.10.1.3
  3. 打开资源设计器,将“访问修饰符”更改为“无代码生成”,并将基础资源文件中的所有键值对复制到新资源文件中。

    7.10.1.4
  4. 列中的所有句子翻译成您的本地语言。

  5. 保存文件并重复相同的操作来创建剩余的文件。

    lblCommon.xx-xx.resx

    MsgRes.xx-xx.resx

    7.10.1.6
  6. 将上述三个文件发送给我(wells-z@hotmail.comwellscheung@gmail.com)。我将整合其他人的资源,并发布一个包含您的语言包的新版本到网站上。谢谢。

测试站点

对于那些想立即测试系统或跟踪bug的同学,我创建了一个测试站点。请访问http://www.wellscom.net。为了保护我们的测试站点,我不得不锁定管理员帐户和函数路径以“0004”开头的函数。并且站点数据将在美国东部时间午夜恢复。

我设置了许多帐户供您测试。

Admin -- Administrator

  • 登录名:admin
  • 密码:123456

Angus – 项目经理

  • 登录名:angus
  • 密码:123456

Wells – 项目团队开发人员

  • 登录名:wells
  • 密码:123456

Alice – 项目团队官员

  • 登录名:alice
  • 密码:123456

Tim – 销售经理

  • 登录名:tim
  • 密码:123456

Michael – 销售

  • 登录名:michael
  • 密码:123456

测试驱动开发

酷权限控制系统采用测试驱动开发(TDD)方法。对于许多公司来说,TDD是重复开发周期中的强制性方法。酷权限控制系统在所有控制器中包含40个测试用例,您可以通过点击测试资源管理器中的“运行所有”轻松测试所有功能。当然,您可以根据您的需求添加新的测试用例或向原始测试用例添加新条件。酷权限控制系统使用Xunit和Mock。Xunit是一个测试框架,注入到Visual Studio中,就像MSTest和Nunit一样。更多信息,您可以访问官方网站。

图 6.0.1 测试资源管理器

最后

酷权限控制基于许多有趣的设计模式,如MVC、MEF、Entity Framework、jQuery和Bootstrap(UI)。很抱歉我不能在短时间内向您介绍所有这些设计模式。如果您对酷权限控制有任何疑问,请随时联系我。感谢您的阅读。

历史

  • 2016年1月22日:首次发布
  • 2016年2月1日:将项目从“酷访问控制”更改为“酷权限控制”,修复了bug和显示问题
  • 2016年2月2日:修复了下载链接的目标
  • 2016年2月8日:WCF服务准备
  • 2016年3月1日:与WCF服务版本合并并添加测试项目
  • 2016年7月18日:将项目移至Github
© . All rights reserved.