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


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

     ——我的名言,呵呵。    

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

          继续,这是第六章了。我发现,越来越难了。终于把表结构都介绍完了,来到了如何应用的阶段了。有回复说我是跳过了设计阶段,恩,设计阶段基本上是在我的脑子里。当然这是一个不好的习惯。不弄出来个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:写了五章了,从大家的回复来看,我心里是很没底的,我不知道大家看懂了没有,有没有什么问题,还是说我写的这些根本就不值得来提问题。或者是比较忙没时间细看。总之,我只能瞎猜,不知道大家的想法到底是什么。

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

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

  • 相关阅读:
    指针,数组,字符串的区别(高质量程序设计指南C++/C语言第7章)
    bitset初始化问题
    书籍
    编译器的工作过程
    C++函数传递指向指针的指针的应用
    程序员面试金典--二叉树的下一个结点
    程序员面试金典--对称的二叉树
    程序员面试金典--按之字形顺序打印二叉树
    程序员面试金典--阶乘尾零
    程序员面试金典--矩阵元素查找
  • 原文地址:https://www.cnblogs.com/jyk/p/1500174.html
Copyright © 2020-2023  润新知