复代码 代码如下:
-- ACL 테이블
-- 表的结构 `aclresources`
DROP TABLE IF 'aclresources'가 존재합니다.
존재하지 않는 경우 테이블 생성 `aclresources` (
`rsid` varchar(64) NOT NULL ,
`access` int(4) NOT NULL 기본값 0,
`desc` varchar(240) NOT NULL 기본값 '',
`created_at` int(10) unsigned NOT NULL 기본값 1,
`updated_at` int(10) unsigned NOT NULL 기본값 0,
PRIMARY KEY(`rsid`)
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- 表的结构 `aclroles`
`aclroles`가 존재하는 경우 DROP TABLE;
`aclroles`가 존재하지 않는 경우 테이블 생성(
`id` int(10) unsigned NOT NULL auto_increment,
`rolename` varchar(32) NOT NULL ,
`desc` varchar(240) NOT NULL 기본값 '',
`created_at` int(10) unsigned NOT NULL 기본값 1,
`updated_at` int(10) unsigned NOT NULL 기본값 0,
PRIMARY KEY(`id`),
고유 키 `역할 이름`(`역할 이름`)
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- 表的结构 `ref_aclresources_aclroles`
`ref_aclresources_aclroles`가 존재하는 경우 테이블 삭제;
존재하지 않는 경우 테이블 생성 `ref_aclresources_aclroles` (
`rsid` varchar(64) NOT NULL ,
`role_id` int(10) unsigned NOT NULL ,
기본 키(`rsid`,` role_id`)
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- 表的结构 `ref_users_aclroles`
`ref_users_aclroles`가 존재하는 경우 테이블 삭제;
존재하지 않는 경우 테이블 생성 `ref_users_aclroles` (
`user_id` int(10) unsigned NOT NULL auto_increment,
`role_id` int(10) unsigned NOT NULL ,
PRIMARY KEY (`user_id` ,`role_id`)
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
-- 表的结构 `users`
`users`가 존재하는 경우 DROP TABLE;
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL auto_increment,
`email` varchar(128) NOT NULL,
`password` varchar(64) NOT NULL,
`nickname` varchar(32) NOT NULL 기본값 '',
`roles` varchar(240) NOT NULL 기본값 '',
`created_at` int(10) unsigned NOT NULL 기본값 1,
`updated_at` int(10) unsigned NOT NULL 기본값 0,
기본 키(`id`),
UNIQUE KEY `user_email`(`email`)
)DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
复代码 代码如下:
/**
* 단순 ACL 권한 제어 기능
*
* 테이블 정의
*
* 1. 리소스 정의(rsid, access, desc, Create_at, update_at)
* 2. 역할 정의 (id, rolename, desc,created_at,update_at)
* 3. 리소스-역할 연결(rsid, role_id)
* 4. 사용자-역할 연결(user_id, role_id)
*
* 따라 다름 db.php에서 sqlobject.php
*
* @author vb2005xu.iteye.com
*/
class AclBase {
// --- ACL 访问授权
/**
* 누구도 접근할 수 없습니다
*/
const NOBODY = 0;
/**
* 누구나 액세스하도록 허용
*/
const EVERYONE = 1;
/**
* 역할이 있는 사용자에게 액세스 허용
*/
const HAS_ROLE = 2;
/**
* 역할이 없는 사용자의 액세스 허용
*/
const NO_ROLE = 3;
/**
* 리소스-역할 연관에 정의된 역할만 액세스할 수 있습니다.
*/
const ALLOCATE_ROLES = 4;
// 특정 이름 지정
public $tbResources = 'aclresources';
공개 $tbRoles = 'aclroles';
공개 $tbRefResourcesRoles = 'ref_aclresources_aclroles';
공개 $tbRefUsersRoles = 'ref_users_aclroles';
/**
* 리소스 액세스 권한 형식 지정 및 반환
*
* @return int
*/
정적 함수 formatAccessValue($access){
정적 $arr = array(self::NOBODY,self::EVERYONE,self::HAS_ROLE,self::NO_ROLE ,자기::ALLOCATE_ROLES);
return in_array($access,$arr) ? $access : 자기::NOBODY;
}
/**
* 리소스 생성 및 리소스 레코드의 기본 키 반환
*
* @param string $rsid
* @param int $access
* @param string $desc
*
* @return int
*/
function createResource($rsid,$access,$desc){
if (empty($rsid)) return false;
$resource = array(
'rsid' => $rsid,
'access' => self::formatAccessValue($access),
'desc' => $desc,
'created_at' => CURRENT_TIMESTAMP
);
return SingleTableCRUD::insert($this->tbResources,$resource);
}
/**
* 리소스 수정 및 성공 상태 반환
*
* @param array $resource
* @return int
*/
function updateResource(array $resource){
if (!isset($resource['rsid'])) return false;
$resource['updated_at'] = CURRENT_TIMESTAMP;
return SingleTableCRUD::update($this->tbResources,$resource,'rsid');
}
/**
* 리소스 삭제
*
* @param string $rsid
* @return int
*/
function deleteResource($rsid){
if (empty($rsid)) return false;
return SingleTableCRUD::delete($this->tbResources,array('rsid'=>$rsid));
}
/**
* 역할 생성 및 역할 레코드 기본 키 반환
*
* @param string $rolename
* @param string $desc
*
* @return int
*/
function createRole($rolename,$desc){
if (empty($rolename)) return false;
$role = array(
'rolename' => $rolename,
'desc' => $desc,
'created_at' => CURRENT_TIMESTAMP
);
SingleTableCRUD::insert($this->tbRoles,$role)를 반환합니다.
}
/**
* 역할 수정 및 성공 상태 반환
*
* @param array $role
* @return int
*/
function updateRole(array $role){
if (!isset($role['id'])) return false;
if (isset($role['rolename'])) unset($role['rolename']);
$role['updated_at'] = CURRENT_TIMESTAMP;
SingleTableCRUD::update($this->tbRoles,$role,'id')를 반환합니다.
}
/**
* 역할 삭제
*
* @param int $role_id
* @return int
*/
function deleteRole($role_id){
if (empty($role_id)) return false;
return SingleTableCRUD::delete($this->tbRoles,array('role_id'=>(int) $role_id));
}
/**
* 리소스에 대한 역할을 지정하고 삽입하기 전에 매번 테이블에서 관련 레코드를 모두 제거합니다.
*
* @param int $rsid
* @param 혼합 $roleIds
* @param boolean $setNull 역할 ID가 존재하지 않는 경우 연관 테이블에서 자원을 지울지 여부
*/
함수 할당RolesForResource($rsid,$roleIds,$setNull=false,$defaultAccess=-1){
if (비어 있음($rsid)) 거짓을 반환;
$roleIds = Normalize($roleIds,',');
if (empty($roleIds)){
if ($setNull){
SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid));
if ($defaultAccess != -1){
$defaultAccess = self::formatAccessValue($defaultAccess);
$this->updateResource(array('rsid'=>$rsid,'access'=>$defaultAccess));
}
true를 반환합니다.
}
false를 반환합니다.
}
SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid));
$roleIds = array_unique($roleIds);
foreach($roleIds를 $role_id로){
SingleTableCRUD::insert($this->tbRefResourcesRoles,array('rsid'=>$rsid,'role_id'=>(int)$role_id) );
}
true를 반환합니다.
}
function cleanRolesForResource($rsid){
if (empty($rsid)) return false;
return SingleTableCRUD::delete($this->tbRefResourcesRoles,array('rsid'=>$rsid));
}
함수 cleanResourcesForRole($role_id){
if (empty($role_id)) return false;
return SingleTableCRUD::delete($this->tbRefResourcesRoles,array('role_id'=>(int) $role_id));
}
/**
* 역할에 리소스를 할당하고, 매번 테이블에서 관련 레코드를 모두 제거한 다음 삽입합니다.
*
* @param int $role_id
* @param 혼합 $rsids
*
* @return 부울
*/
function 할당ResourcesForRole($role_id,$rsids){
if (empty($role_id)) return false;
$role_id = (int) $role_id;
$rsids = 정규화($rsids,',');
if (empty($rsids)){
false를 반환;
}
SingleTableCRUD::delete($this->tbRefResourcesRoles,array('role_id'=>$role_id));
$rsids = array_unique($rsids);
foreach($rsid를 $rsid로){
SingleTableCRUD::insert($this->tbRefResourcesRoles,array('rsid'=>$rsid,'role_id'=>$role_id));
}
true를 반환합니다.
}
/**
* 사용자에게 역할을 할당하고, 삽입하기 전에 매번 테이블에서 관련 레코드를 모두 제거합니다.
*
* 여기서 사용자가 많으면 성능 문제가 발생할 수 있습니다. 나중에 최적화하세요.
*
* @param int $user_id
* @param 혼합 $roleIds
*
* @return boolean
*/
function 할당RolesForUser($user_id,$roleIds){
if (empty($user_id)) return false;
$user_id = (int) $user_id;
$roleIds = Normalize($roleIds,',');
if (empty($roleIds)){
false를 반환;
}
SingleTableCRUD::delete($this->tbRefUsersRoles,array('user_id'=>$user_id));
$roleIds = array_unique($roleIds);
foreach($roleId를 $roleId로){
SingleTableCRUD::insert($this->tbRefUsersRoles,array('user_id'=>$user_id,'role_id'=>$role_id));
}
true를 반환합니다.
}
/**
* 사용자 역할 정보 지우기
*
* @param int $user_id
*
* @return boolean
*/
function cleanRolesForUser($user_id){
if (empty($user_id)) return false;
return SingleTableCRUD::delete($this->tbRefUsersRoles,array('user_id'=>(int) $user_id));
}
/**
* 역할의 사용자 연결 지우기
*
* @param int $role_id
*
* @return boolean
*/
function cleanUsersForRole($role_id){
if (empty($role_id)) return false;
return SingleTableCRUD::delete($this->tbRefUsersRoles,array('role_id'=>(int) $role_id));
}
}
复主代码 代码如下:
/**
* 리소스에 대한 ACL 확인 수행
*
* @param string $rsid 리소스 식별자
* @param array $user 특정 사용자, 지정되지 않은 경우 현재 사용자 확인
*
* @return 부울
*/
function aclVerity($rsid ,array $user = null){
if (empty($rsid)) return false;
if (!CoreApp::$defaultAcl) {
CoreApp::$defaultAcl = new AclFlat();
}
$rsRow = aclGetResource($rsid);
// 未定义资源的缺省访问策略
if (!$rsRow) return false;
CoreApp::writeLog($rsRow,'test');
$rsRow['access'] = AclBase::formatAccessValue($rsRow['access']);
// 允许任何人访问
if (AclBase::EVERYONE == $rsRow['access']) return true;
// 不允许任何人访问
if (AclBase::NOBODY == $rsRow['access']) return false;
// 获取用户信息
if (empty($user)) $user = isset($_SESSION['SI-SysUser']) ? $_SESSION['SI-SysUser'] : null;
// 用户未登录,则当成无访问权限
if (empty($user)) return false;
$user['roles'] = 비어 있음($user['roles']) ? null : Normalize($user['roles'],';');
$userHasRoles = !empty($user['roles']);
/**
* 역할이 없는 사용자의 액세스 허용
*/
if (AclBase::NO_ROLE == $rsRow['access']) return $userHasRoles ? 거짓 : 사실;
/**
* 역할이 있는 사용자에게 액세스 허용
*/
if (AclBase::HAS_ROLE == $rsRow['access']) return $userHasRoles ? 사실 : 거짓;
// --- 对用户进行 资源 <-> 角color 校验
if ($userHasRoles){
foreach ($user['roles'] as $role_id){
if ( aclGetRefResourcesRoles($rsid,$role_id) )
return true;
}
dump($user);
}
false를 반환합니다.
}
复代码 代码如下:
/**
* 리소스에 대한 ACL 확인 수행
*
* @param string $rsid 리소스 식별자
* @param array $user 특정 사용자, 지정되지 않은 경우 현재 사용자 확인
*
* @return 부울
*/
function aclVerity($rsid ,array $user = null){
if (empty($rsid)) return false
if (! CoreApp::$defaultAcl) {
CoreApp::$defaultAcl = new AclFlat();
}
$rsRow = aclGetResource($rsid)
// 정의되지 않은 리소스에 대한 기본 액세스 정책
if (!$rsRow) return false;
CoreApp::writeLog($rsRow,'test')
/*
* 확인 단계는 다음과 같습니다.
*
* 1. 먼저 리소스 자체의 액세스 속성을 확인합니다
* EVERYONE => true, NOBODY => false * 아래의 다른 속성도 계속 확인합니다
* 2. 세션(또는 사용자 세션 테이블)에서 역할을 가져옵니다. ID 수집
* 3. 사용자에게 역할이 있는 경우 HAS_ROLE => true, NO_ROLE => false, 그 반대
* 4. 리소스 액세스 == ALLOCATE_ROLES
* 1. 캐시에서(또는 Get $tbRefResourcesRoles에서 리소스에 해당하는 역할 ID 집합)
* 2. 사용자가 소유한 역할 ID 집합과 리소스에 해당하는 역할 ID 집합의 교차점을 찾습니다
* 3. 교차점 존재=> true; else=> false
*/
$rsRow['access'] = AclBase::formatAccessValue($rsRow['access'])
// 다음과 같은 경우 누구나 액세스 허용
(AclBase::EVERYONE = = $rsRow['access']) return true;
// 누구에게도 액세스를 허용하지 않습니다.
if (AclBase::NOBODY == $rsRow['access']) return false ;
// 사용자 정보 가져오기
if (empty($user)) $user = isset($_SESSION['SI-SysUser']) : null
// 사용자가 로그인되어 있지 않으면 접근 권한이 없는 것으로 처리됩니다.
if (empty($user)) return false
$user['roles'] =empty($user['roles; ']) ? null : Normalize($user['roles'],';');
$userHasRoles = !empty($user['roles'])
/**
* 역할이 없는 사용자의 액세스 허용
*/
if (AclBase::NO_ROLE == $rsRow ['access']) return $userHasRoles ? false :
/**
* 역할이 있는 사용자에게 액세스 허용
*/
if (AclBase::HAS_ROLE == $ rsRow['access']) return $userHasRoles ? true : false
// --- 사용자에 대한 리소스<->if ($userHasRoles){
foreach ($user[' 역할'] as $role_id){
if ( aclGetRefResourcesRoles($rsid,$role_id) )
return true;
}
dump($user)
}
return false ;
}
/* *
* 역할 리소스 액세스 제어 목록 재생성
*
* @param string $actTable ACL 테이블 이름
* @param boolean $return 재생성된 목록 반환 여부
*
* @return 혼합
*/
function aclRebuildACT($actTable ,$return = false){
if (empty($actTable)) return false
global $ globalConf;
$rst = null
$cacheId = null
switch($actTable){
case CoreApp::$defaultAcl->tbResources:
$cacheId = 'acl- resources';
$rst = SingleTableCRUD ::findAll(CoreApp::$defaultAcl->tbResources)
//해시 테이블 구조로 변환
if ($rst){
$rst = array_to_hashmap($rst,'rsid') ;
}
break;
case CoreApp::$defaultAcl->tbRoles:
$cacheId =
$rst = SingleTableCRUD::findAll(CoreApp:: $defaultAcl->tbRoles);
//해시 테이블 구조로 변환
if ($rst){
$rst = array_to_hashmap($rst,'id' );
}
break;
case CoreApp::$defaultAcl->tbRefResourcesRoles:
$cacheId = 'acl-roles_has_resources'
$rst = SingleTableCRUD::findAll(CoreApp: :$defaultAcl->tbRefResourcesRoles) ;
if ($rst){
$_ = array()
foreach ($rst as $row) {
$ref_id = "{$row ['rsid']}< -|->{$row['role_id']}";
$_[$ref_id] = $row;
}
unset($rst);
$rst = $_
}
break;
}
if ($cacheId)
writeCache($globalConf['runtime']['cacheDir'] ,$cacheId ,$rst ,true);
if ($return) return $rst;
/**
* 역할 리소스 액세스 제어 목록 데이터 가져오기
*
* @param string $actTable ACL 테이블 이름
*
* @return 혼합
*/
function aclGetACT($actTable){
if (비어 있음) ($actTable)) return false;
static $rst = array();
$cacheId = null
switch($actTable){
case CoreApp::$defaultAcl->tbResources:
$cacheId = 'acl -resources';
break
case CoreApp::$defaultAcl->tbRoles:
$cacheId = 'acl-roles'
case CoreApp::$defaultAcl- >tbRefResourcesRoles:
$cacheId = 'acl-roles_has_resources';
break;
}
if (!$cacheId) return null; isset($rst[$cacheId] )) return $rst[$cacheId];
global $globalConf
// 900
$rst[$cacheId] = getCache($globalConf['runtime'] ['cacheDir'],$cacheId ,0);
if ( !$rst[$cacheId] ){
$rst[$cacheId] = aclRebuildACT($actTable,true)
return $rst[$cacheId] ;
}
/**
* 리소스 레코드 가져오기
*
* @param string $rsid
*
* @return array
*/
function aclGetResource($rsid){
static $rst = null; rst){
$rst = aclGetACT(CoreApp::$defaultAcl->tbResources);
if (!$rst) $rst = array()
}
return isset($rst) [$rsid]) ? $rst [$rsid] : null
}
/**
* 역할 기록 가져오기
*
* @param int $role_id
*
* @return array
*/
함수 aclGetRole($role_id){
static $rst = null
if (!$rst){
$rst = aclGetACT(CoreApp: :$defaultAcl->tbRoles);
if (!$rst) $rst = array()
}
return isset($rst[$role_id]) ? null;
}
/**
* 사용자 역할 관련 레코드를 가져옵니다. 이 방법을 사용하면 이 역할에서 리소스를 호출할 수 있는지 확인할 수 있습니다.
*
* @param string $rsid
* @param int $role_id
*
* @return 배열
*/
함수 aclGetRefResourcesRoles($rsid,$role_id){
static $rst = null
if(!$rst){
$rst = aclGetACT(CoreApp::$defaultAcl->tbRefResourcesRoles);
if (!$rst) $rst = array()
}
$ref_id = "{$rsid}< ;-|->{$role_id}";
CoreApp::writeLog(isset($rst[$ref_id])?$rst[$ref_id]:'nodata',$ref_id);
isset 반환 ($rst[$ref_id]) ? $rst[$ref_id] : null
}
이상에서는 acrobat professional 9.0의 내용을 포함하여 acrobat professional 9.0 php에서 간단한 ACL 구현 완료를 소개하였습니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되었으면 좋겠습니다.