zoukankan      html  css  js  c++  java
  • 妙用sql的统计进行集合的比较

      在阳光网改版过程中,引入的权限控制是个让人喜爱又头疼的问题。

      假如所有的权限或者资源数据是静态的化,我会非常喜欢,因为通过简单的代码和控制策略就可以提升系统的安全性。

      但,这是不可能的。在权限系统中,所有的资源应该能够动态的添加和增加。尤其在未来的某段时间内,阳光网的所有资源进行整合的时候,添加增减资源将会时常的发生。更为重要的,让系统能够容纳更多的用户进行系统内部的控制,一个必然的需求,就是让系统更灵活,更好的实现不同场景下,资源的分配和组织。

      所有的问题都来自于动态的组织上,下面是其中的一方面。

      在权限模块中,我们采用的3张表(此次问题涉及的3站,在实际控制中,权限表较多),role,module,operation。分别对应角色,模块和操作,模块用来组织操作,便于操作的分配。

      在控制环境中,这些表的关系再复杂都不会影响权限的控制,但在存在多层分类,如角色,子角色;模块,子模块,的时候,界面元素的分配将成为一个问题。

      默认情况下一个模块绑定一个界面元素。这是最完美的情况。对于代码而言,就是获取角色关联的模块,然后呈现与资源进行绑定的模块,一气呵成。

      此情况在开始开发系统的时候是比较常见的,但在随后的过程中,一个模块可能不再与一个界面资源绑定;或者一个角色所关联的模块自身没有界面资源,但其操作进行重组后的模块确是绑定界面资源的,这个比较复杂。

      举例

      角色a->模块a->操作1操作2操作3

      角色b->(模块b->操作1操作2),(模块c>操作3)

      其中模块b,c与界面资源进行了合理的绑定(为了呈现而采用的一种web动态布局方式);而界面模块a没有。对于分配到角色b的用户来说,没有任何界面资源的控制问题;倘若用户a同时拥有角色a,b,那么很幸运,通过角色查询到的模块b,c就可以呈现出界面资源;但用户b只具有模块a,从权限上考虑,用户b具有进行操作1操作2操作3的使用权,这在桌面系统中(无图形桌面,只是用控制命令),这是完全合理的。但WEB就不行。

      唯一的解决策略就是反向查找。

      具体通过角色a查找到所有有效操作,再将操作反向到所有可能的模块。

      思路很简单,但编程却不容易。在我们的系统中,角色模块是动态的,一个用户的多个角色需要进行合并,多个角色关联的多个模块同样需要合并同时去除重复项。实际过程中是够复杂的。

       但若站在数据库层次考虑(这是我比较赞同的思考方向,对于基于数据库的应用,数据的控制问题尽量不干预业务),需要以下形式的sql语句经行查询就可以获取需要的数据。

      SELECT DISTINCT temp1.ModuleID

      FROM

      (
         SELECT oinm1.ModuleID,COUNT(DISTINCT oinm1.OperationID) AS opsum
         FROM OperationInModule AS oinm1, OperationInModule AS oinm2
         WHERE oinm1.OperationID = oinm2.OperationID AND oinm2.ModuleID
          IN
          (
             SELECT DISTINCT rbac_minr.ModuleID
             FROM ModuleInRole AS rbac_minr,  UserInRoles as rbac_uinr
             WHERE rbac_minr.RoleID = rbac_uinr.RoleID AND rbac_uinr.UserID = @UserID
          )
         GROUP BY oinm1.ModuleID
      ) AS temp1,
      (
         SELECT ModuleID,COUNT(*) AS opsum
         FROM OperationInModule     GROUP BY ModuleID
      )  AS temp2
      WHERE temp1.ModuleID = temp2.ModuleID AND temp1.opsum = temp2.opsum
      虽然省略的关系表,但通过sql语句还是很明显理解其中的表关系的。在这个查询过程中,通过sql的统计就可以轻松的实现集合的比较。由此就可以有效地解决模块的方向查找的问题。

      界面和模块的分配由此可以完成,可以说算得上圆满。但另有一个问题又浮出水面。如果模块a也绑定了界面资源,但和模块b的界面资源又不一样。对于一个同时拥有角色ab的用户来说,上面的方向查询能够获得模块a,b,具体呈现哪一种界面资源;还有一些情况更复杂,在此就不说了。

  • 相关阅读:
    <转>反调试技巧总结原理和实现
    反调试功能<IsDebuggerPresent>
    通过取得MAC地址判断是否在VM中
    任何值得拥有的东西
    我的程序里
    吸引力法则之谜——十一条被遗忘的定律
    要成功,请忘掉自尊
    我是个只顾着想,却不去做的人
    现在有12个金币,其中一个有质量问题(或重或轻),还有一个无砝码的天平,让你称三次怎么样找到那个有质量问题的金币?
    惆怅
  • 原文地址:https://www.cnblogs.com/kathmi/p/1418471.html
Copyright © 2011-2022 走看看