【自然框架】之通用权限(六):权限到节点

      “直率没有错,但是也要考虑对方的承受能力呀!对方都承受不了了,你还直率,那就是你的错了!”

 ——我的名言,呵呵。    

====================我就是传说中的,可爱的、无奈的、笑笑而过的分割线====================

      继续,这是第六章了。我发现,越来越难了。终于把表结构都介绍完了,来到了如何应用的阶段了。有回复说我是跳过了设计阶段,恩,设计阶段基本上是在我的脑子里。当然这是一个不好的习惯。不弄出来个UML、ER这样的东东,别人怎么理解呢?又怎么能够严谨呢?不过不管怎么说,我还是要把我的想法、数据库表、实现方法、代码、Demo都拿出来,希望没有污染大家的眼睛。

      不管我的东东好与不好,至少我是拿出来了,虽然还没有写完,但是没有严重的意外的话,我会坚持下去的。

通用权限想要写的文章目录:(这是第六章)

1、 简介、数据库的总体结构 2、 介绍人员表组 3、 介绍组织结构表组 4、 介绍角色表组 5、 介绍“项目自我描述表组” 6、 权限到节点 7、 权限到按钮 8、 权限到列表(表单、查询) 9、 权限的验证 10、 资源方面的权限 11、 角色管理的程序(给客户用的) 12、 权限下放 13、 个性化设置 A、 【自然框架】之通用权限(外传):杂谈

功能节点

【图一:功能节点的效果】

【图二:功能节点的数据】

      先说一下功能节点,先看图一,左面的就是我所说的功能节点,这个节点是根据Manage_Function表里的数据显示的,就是说每一个节点都放在了表里面,显示的时候、提取数据然后绑定就可以了。

      如果您查看WebUrl字段(图二),您会发现只有一个节点是Excel.aspx,其余的节点都是DataList.aspx。您是不是会想,这个是不是我写错了?或者是节点的功能还没有实现,先用了一个DataList.aspx来代替?这个没有写错,也不是临时占位用的。在自然架构里面,增删改查这一类的列表页面,95%以上都可以使用DataList.aspx页面。

      在功能节点上面,单击一个节点以后,会根据节点里的WebUrl字段信息打开网页,然后会在网页后面加上一个参数?fid=xxx。这个fid就是FunctionID。就是说通过单击节点的方式进入的页面都会得到一个FunctionID的参数。这个参数是很有用处的,可以做很多的事情,比如做权限验证。稍后会有说明。

      这里有一个特殊的字段sort,这个可能比较少见,也可能是一个不严谨的设计。这个字段的功能就是 —— 排序,对所有的节点进行排序。按照这个字段排序的结果,就是页面里面要达到显示顺序,这样就避免的在显示的时候的使用“递归”的方式。不知道有没有其他的非递归的方式,总之我是采用了这种方法。

权限到节点

      说起来简单,正常提取数据的SQL语句是这样的。

string sql = "SELECT FunctionID, NoteTitle, NoteLevel, ParentIDPath, WebURL, Target FROM Manage_Function where IsShowNote = 1 ORDER BY  Sort";
 
 DataTable dt = dal.ExecuteFillDataTable(sql);
 
 Rpt.DataSource = dt;     //绑定到Repeater
 Rpt.DataBind();

      那么加上权限呢?

      角色表Role_Role里面的FunctionIDs 字段里面存放的就是角色可以访问的功能节点的ID的集合。比如我们建立一个“字典信息管理角色”,那么这个角色里面的FunctionIDs就是这样的“8,9,10,11,12,13,14,15,16”。

     然后我们可以把FunctionIDs的值取出来,然后写成FunctionID in () 的形式就可以了。 代码如下。

//加入权限
 string FunctionIDs = JYK.Common.UserManage.UserInfo.FunctionIDs;    //获取登录人可以访问的节点ID。
 
 string sql = "SELECT FunctionID, NoteTitle, NoteLevel, ParentIDPath, WebURL, Target FROM Manage_Function where FunctionID in (" + FunctionIDs + ") and IsShowNote = 1 ORDER BY  Sort";
 DataTable dt = dal.ExecuteFillDataTable(sql);
 
 Rpt.DataSource = dt;
 Rpt.DataBind();

列表页面验证

      只是做到功能节点的显示与否这还不够,因为用户可以通过,直接在浏览器的地址栏里面输入网址的形式访问列表页面。所以呢,还需要在列表页面里进行验证。

      列表页面里的验证分为两步,第一步验证传递进来的FunctionID是否是希望得到的。第二步是验证用户是否有权限访问这个FunctionID。

      第一步好做,写一个if就可以了,第二步也简单,使用IndexOf就可以了。

      对于DataList.aspx页面来说,任何一个FunctionID都是可以传递进来的,他可以根据这个FunctionID的不同而显示不同的页面。也就是说对于DataList.aspx只需要进行第二步的验证就可以了。

何谓通用?

      1、功能节点的显示:只看Manage_Function里的记录,不用考虑业务需求,不用考虑项目里有哪些具体的功能节点。只要能够把业务需求变成功能节点的形式,写到Manage_Function表里面,那么就可以这种方式来显示成功能节点的形式。增加一个节点,减少一个节点,都不需要修改代码。增加一个节点,也就是在表里面添加一条记录,添加后会得到一个FunctionID,这个FunctionID就是这个节点的权限标志。

      2、权限到节点:只需要加一个查询条件 FunctionID in () 就可以了,他只认FunctionID,不用考虑项目里面到底有哪些功能,有哪些节点。而角色表里面只需要记录可以访问的FunctionID就可以了。增加一个节点,减少一个节点,也不需要修改角色方面的代码,只需要调整一下Role_Role表里的记录。当然了,也不需要打开企业管理器来调整,我们可以写一个维护角色的功能(页面),用这个页面,客户自己都可以管理角色。

      3、列表页面的验证:这个也是很简单的,抽象出来两个函数,然后在页面里调用一下就可以了。对于DataList.aspx页面来说就更简单了。

      我想这就是通用吧。我把功能节点的现实与否变成了查询条件,我把权限的验证变成了检查数据库里有无匹配的记录。因为我是面向数据库的,所以我就这么做了。       还记得《我写项目的思路和“自然架构”》里面的那张图吗?

数据库作为间隔,把业务逻辑和实现代码给分离开来。现在从角色方面来看,确实做到了这一点。角色只对数据库(特定表里的数据)说话,不用考虑具体的业务需求。而数据库里的记录是根据具体的业务需求而添加的,添加了就可以了,不用去管具体的代码实现。

一个人拥有多个角色怎么办?

      我的角色分为了两种,一种我叫做“正向角色”,就是规定可以访问哪些。另一种我叫做“拒绝角色”,就是规定不可以访问哪些。那么这些角色遇到一起会是什么样子呢?

      1、多个正向角色,他们是“或”的关系,就是说只要有一个角色规定了可以访问,那么就是可以访问的。

      2、正向角色与拒绝角色相遇,那么拒绝角色就是“一票否决制”,只要是它规定的不可以访问的节点,那么拥有在多的正向角色都是不能访问这个节点的。

      3、拒绝角色的验证。先到拒绝角色的FunctionIDs里面找,如果传递进来的FunctionID在这个集合里面,那么就不能访问了。如果不在这个集合里面,那么再到正向角色的FunctionIDs里面找,如果在这个几个里面,那么就可以访问。

      4、为什么要用“拒绝角色”

      举个例子吧,就拿上面的“字典信息管理角色”来说,一般情况下,这个角色要包含字典信息里的所有的节点。但是有一天遇到一个特殊情况,某人可以访问字典信息里的节点,但是却不可以访问“表类型”这个节点。那么怎么办呢?

      我们可以再定义一个角色,这个角色包含除“表类型”外的所有的字典信息里的节点。这是一种办法,另一种就是“拒绝角色”。

      我们可以添加一个拒绝角色,这个拒绝角色就叫做“字典信息管理角色表类型除外”(一时想不出来好名字),这个拒绝角色“继承”(或者叫做关联)“字典信息管理角色”,通过“继承”的方式获得了“字典信息管理角色”的全部功能,然后在这个基础上,加上一个“拒绝”,就是说明要拒绝“表类型”节点的访问。

      这么做操作起来可以方便一些,可以达到继承的一些效果。比如,字典信息里面又增加了一个节点“角色类型”,那么上面说的两种情况都可以访问,那就只需要修改“字典信息管理角色”就可以了。

      这么做我想思路会更清晰一些。客户也应该更容易理解一些。

ps:写了五章了,从大家的回复来看,我心里是很没底的,我不知道大家看懂了没有,有没有什么问题,还是说我写的这些根本就不值得来提问题。或者是比较忙没时间细看。总之,我只能瞎猜,不知道大家的想法到底是什么。

所以呢,现在也到了具体的应用的阶段了,希望大家踊跃回复哦,只要回复不包含人身攻击,那就都没有问题。你说我的程序烂,不严谨,都可以,当然希望能够详细说明。帮我挑毛病,我是要感谢大家的。我对大家的疑问也会一一回复的。

您的回复,就是我前进的动力!谢谢大家!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Pulsar-V

PHP微信开发入门(二)

微信服务器消息推送 微信的消息推送方式是客户操作微信发生一系列事件,然后腾讯微信服务器发送一个XML数据POST请求把事件描述发送到你填写的服务器URL上,你的...

4426
来自专栏MongoDB中文社区

MongoDB 新功能介绍-Change Streams

MongoDB 3.6已经GA有一段时间,网络上对于该版本新特性的详细介绍文章比较少为此借机会对部分新特性做一个相对详细的介绍。基于早期MongoDB版本实现如...

3722
来自专栏李家的小酒馆

通过Python实现一个文档的半自动录入工具

  因为公司需要将word办的接口文档在线化,看起来是个很好的事情,但是就是苦逼了我们这些干活的,其中工程量最大的就是参数的录入,要是参数少也罢,有的接口动辄三...

1111
来自专栏我的安全视界观

【一起玩蛇】Nodejs代码审计中的器

5636
来自专栏沃趣科技

按 host 分组统计视图 | 全方位认识 sys 系统库

在上一篇《配置表 | 全方位认识 sys 系统库》中,我们介绍了sys 系统库的配置表,但实际上我们大部分人大多数时候并不需要去修改配置表,直接使用sys 系统...

1664
来自专栏烂笔头

在Python应用中使用MongoDB

目录[-] Python是开发社区中用于许多不同类型应用的强大编程语言。很多人都知道它是可以处理几乎任何任务的灵活语言。因此,在Python应用中需要一个...

4384
来自专栏大内老A

《WCF技术剖析》博文系列汇总[持续更新中]

近半年以来,一直忙于我的第一本WCF专著《WCF技术剖析(卷1)》的写作,一直无暇管理自己的Blog。在《WCF技术剖析(卷1)》写作期间,对WCF又有了新的感...

1768
来自专栏FreeBuf

Flash XSS检测脚本的简单实现

前言 这里主要是讲如何快速扫描到有问题的flash文件,用于批量,有时候很笨的方法也会有奇效,下面记录一下在实现过程中的一些思路和遇到的一些坑。 ? 第三方插件...

3055
来自专栏pangguoming

Ubuntu安装nodeJS

安装环境 ubuntu12.04 64bit  nodejs-v0.8.14.tar.gz  Node.js是一个基于google v8+javascript的...

4964
来自专栏玄魂工作室

老司机教你下载tumblr上视频和图片的正确姿势

本文面向初学者。 很多同学问我:“我非常想学Python编程,但是找不到兴趣点”。 还有的同学呢,找到了很好的兴趣点,但是无从下手,“玄魂老师,我想下载tumb...

1.3K7

扫码关注云+社区

领取腾讯云代金券