ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 【自然框架】之通用权限(六):权限到节点

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

原创 Linux操作系统 作者:iDotNetSpace 时间:2009-07-28 11:21:12 0 删除 编辑

功能节点

 

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

 

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

 

      先说一下功能节点,先看图一,左面的就是我所说的功能节点,这个节点是根据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:写了五章了,从大家的回复来看,我心里是很没底的,我不知道大家看懂了没有,有没有什么问题,还是说我写的这些根本就不值得来提问题。或者是比较忙没时间细看。总之,我只能瞎猜,不知道大家的想法到底是什么。

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

原文地址:http://jyk.cnblogs.com/jyk/archive/2009/06/10/1500174.html

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12639172/viewspace-610615/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-01-04

  • 博文量
    2376
  • 访问量
    5297106