PageRenderTime 24ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/yourphp/App/Lib/ORG/RBAC.class.php

https://gitlab.com/selecterskyphp/framework
PHP | 250 lines | 167 code | 9 blank | 74 comment | 30 complexity | 39294338636ff95bbf482821abb782d8 MD5 | raw file
Possible License(s): Apache-2.0
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: liu21st <liu21st@gmail.com>
  10. // +----------------------------------------------------------------------
  11. // $Id$
  12. /**
  13. +------------------------------------------------------------------------------
  14. * 基于角色的数据库方式验证类
  15. +------------------------------------------------------------------------------
  16. * @category ORG
  17. * @package ORG
  18. * @subpackage Util
  19. * @author liu21st <liu21st@gmail.com>
  20. * @version $Id$
  21. +------------------------------------------------------------------------------
  22. */
  23. // 配置文件增加设置
  24. // USER_AUTH_ON 是否需要认证
  25. // USER_AUTH_TYPE 认证类型
  26. // USER_AUTH_KEY 认证识别号
  27. // REQUIRE_AUTH_MODULE 需要认证模块
  28. // NOT_AUTH_MODULE 无需认证模块
  29. // USER_AUTH_GATEWAY 认证网关
  30. class RBAC extends Think
  31. {
  32. // 认证方法
  33. static public function authenticate($map,$model='')
  34. {
  35. if(empty($model)) $model = C('USER_AUTH_MODEL');
  36. //使用给定的Map进行认证
  37. return M($model)->where($map)->find();
  38. }
  39. //用于检测用户权限的方法,并保存到Session中
  40. static function saveAccessList($authId=null)
  41. {
  42. if(null===$authId) $authId = $_SESSION[C('USER_AUTH_KEY')];
  43. // 如果使用普通权限模式,保存当前用户的访问权限列表
  44. // 对管理员开发所有权限
  45. if(C('USER_AUTH_TYPE') !=2 && !$_SESSION[C('ADMIN_AUTH_KEY')] )
  46. $_SESSION['_ACCESS_LIST'] = RBAC::getAccessList($authId);
  47. return ;
  48. }
  49. // 取得模块的所属记录访问权限列表 返回有权限的记录ID数组
  50. static function getRecordAccessList($authId=null,$module='') {
  51. if(null===$authId) $authId = $_SESSION[C('USER_AUTH_KEY')];
  52. if(empty($module)) $module = MODULE_NAME;
  53. //获取权限访问列表
  54. $accessList = RBAC::getModuleAccessList($authId,$module);
  55. return $accessList;
  56. }
  57. //检查当前操作是否需要认证
  58. static function checkAccess()
  59. {
  60. //如果项目要求认证,并且当前模块需要认证,则进行权限认证
  61. if( C('USER_AUTH_ON') ){
  62. $_module = array();
  63. $_action = array();
  64. if("" != C('REQUIRE_AUTH_MODULE')) {
  65. //需要认证的模块
  66. $_module['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_MODULE')));
  67. }else {
  68. //无需认证的模块
  69. $_module['no'] = explode(',',strtoupper(C('NOT_AUTH_MODULE')));
  70. }
  71. //检查当前模块是否需要认证
  72. if((!empty($_module['no']) && !in_array(strtoupper(MODULE_NAME),$_module['no'])) || (!empty($_module['yes']) && in_array(strtoupper(MODULE_NAME),$_module['yes']))) {
  73. if("" != C('REQUIRE_AUTH_ACTION')) {
  74. //需要认证的操作
  75. $_action['yes'] = explode(',',strtoupper(C('REQUIRE_AUTH_ACTION')));
  76. }else {
  77. //无需认证的操作
  78. $_action['no'] = explode(',',strtoupper(C('NOT_AUTH_ACTION')));
  79. }
  80. //检查当前操作是否需要认证
  81. if((!empty($_action['no']) && !in_array(strtoupper(ACTION_NAME),$_action['no'])) || (!empty($_action['yes']) && in_array(strtoupper(ACTION_NAME),$_action['yes']))) {
  82. return true;
  83. }else {
  84. return false;
  85. }
  86. }else {
  87. return false;
  88. }
  89. }
  90. return false;
  91. }
  92. // 登录检查
  93. static public function checkLogin() {
  94. //检查当前操作是否需要认证
  95. if(RBAC::checkAccess()) {
  96. //检查认证识别号
  97. if(!$_SESSION[C('USER_AUTH_KEY')]) {
  98. if(C('GUEST_AUTH_ON')) {
  99. // 开启游客授权访问
  100. if(!isset($_SESSION['_ACCESS_LIST']))
  101. // 保存游客权限
  102. RBAC::saveAccessList(C('GUEST_AUTH_ID'));
  103. }else{
  104. // 禁止游客访问跳转到认证网关
  105. redirect(PHP_FILE.C('USER_AUTH_GATEWAY'));
  106. }
  107. }
  108. }
  109. return true;
  110. }
  111. //权限认证的过滤器方法
  112. static public function AccessDecision($appName=APP_NAME)
  113. {
  114. //检查是否需要认证
  115. if(RBAC::checkAccess()) {
  116. //存在认证识别号,则进行进一步的访问决策
  117. $accessGuid = md5($appName.MODULE_NAME.ACTION_NAME);
  118. if(empty($_SESSION[C('ADMIN_AUTH_KEY')])) {
  119. if(C('USER_AUTH_TYPE')==2) {
  120. //加强验证和即时验证模式 更加安全 后台权限修改可以即时生效
  121. //通过数据库进行访问检查
  122. $accessList = RBAC::getAccessList($_SESSION[C('USER_AUTH_KEY')]);
  123. }else {
  124. // 如果是管理员或者当前操作已经认证过,无需再次认证
  125. if( $_SESSION[$accessGuid]) {
  126. return true;
  127. }
  128. //登录验证模式,比较登录后保存的权限访问列表
  129. $accessList = $_SESSION['_ACCESS_LIST'];
  130. }
  131. //判断是否为组件化模式,如果是,验证其全模块名
  132. $module = defined('P_MODULE_NAME')? P_MODULE_NAME : MODULE_NAME;
  133. if(!isset($accessList[strtoupper($appName)][strtoupper($module)][strtoupper(ACTION_NAME)])) {
  134. $_SESSION[$accessGuid] = false;
  135. return false;
  136. }
  137. else {
  138. $_SESSION[$accessGuid] = true;
  139. }
  140. }else{
  141. //管理员无需认证
  142. return true;
  143. }
  144. }
  145. return true;
  146. }
  147. /**
  148. +----------------------------------------------------------
  149. * 取得当前认证号的所有权限列表
  150. +----------------------------------------------------------
  151. * @param integer $authId 用户ID
  152. +----------------------------------------------------------
  153. * @access public
  154. +----------------------------------------------------------
  155. */
  156. static public function getAccessList($authId)
  157. {
  158. // Db方式权限数据
  159. $db = Db::getInstance();
  160. $table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'),'node'=>C('RBAC_NODE_TABLE'));
  161. $sql = "select node.id,node.name from ".
  162. $table['role']." as role,".
  163. $table['user']." as user,".
  164. $table['access']." as access ,".
  165. $table['node']." as node ".
  166. "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=1 and node.status=1";
  167. $apps = $db->query($sql);
  168. $access = array();
  169. foreach($apps as $key=>$app) {
  170. $appId = $app['id'];
  171. $appName = $app['name'];
  172. // 读取项目的模块权限
  173. $access[strtoupper($appName)] = array();
  174. $sql = "select node.id,node.name from ".
  175. $table['role']." as role,".
  176. $table['user']." as user,".
  177. $table['access']." as access ,".
  178. $table['node']." as node ".
  179. "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=2 and node.pid={$appId} and node.status=1";
  180. $modules = $db->query($sql);
  181. // 判断是否存在公共模块的权限
  182. $publicAction = array();
  183. foreach($modules as $key=>$module) {
  184. $moduleId = $module['id'];
  185. $moduleName = $module['name'];
  186. if('PUBLIC'== strtoupper($moduleName)) {
  187. $sql = "select node.id,node.name from ".
  188. $table['role']." as role,".
  189. $table['user']." as user,".
  190. $table['access']." as access ,".
  191. $table['node']." as node ".
  192. "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
  193. $rs = $db->query($sql);
  194. foreach ($rs as $a){
  195. $publicAction[$a['name']] = $a['id'];
  196. }
  197. unset($modules[$key]);
  198. break;
  199. }
  200. }
  201. // 依次读取模块的操作权限
  202. foreach($modules as $key=>$module) {
  203. $moduleId = $module['id'];
  204. $moduleName = $module['name'];
  205. $sql = "select node.id,node.name from ".
  206. $table['role']." as role,".
  207. $table['user']." as user,".
  208. $table['access']." as access ,".
  209. $table['node']." as node ".
  210. "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.node_id=node.id and node.level=3 and node.pid={$moduleId} and node.status=1";
  211. $rs = $db->query($sql);
  212. $action = array();
  213. foreach ($rs as $a){
  214. $action[$a['name']] = $a['id'];
  215. }
  216. // 和公共模块的操作权限合并
  217. $action += $publicAction;
  218. $access[strtoupper($appName)][strtoupper($moduleName)] = array_change_key_case($action,CASE_UPPER);
  219. }
  220. }
  221. return $access;
  222. }
  223. // 读取模块所属的记录访问权限
  224. static public function getModuleAccessList($authId,$module) {
  225. // Db方式
  226. $db = Db::getInstance();
  227. $table = array('role'=>C('RBAC_ROLE_TABLE'),'user'=>C('RBAC_USER_TABLE'),'access'=>C('RBAC_ACCESS_TABLE'));
  228. $sql = "select access.node_id from ".
  229. $table['role']." as role,".
  230. $table['user']." as user,".
  231. $table['access']." as access ".
  232. "where user.user_id='{$authId}' and user.role_id=role.id and ( access.role_id=role.id or (access.role_id=role.pid and role.pid!=0 ) ) and role.status=1 and access.module='{$module}' and access.status=1";
  233. $rs = $db->query($sql);
  234. $access = array();
  235. foreach ($rs as $node){
  236. $access[] = $node['node_id'];
  237. }
  238. return $access;
  239. }
  240. }//end class
  241. ?>