任何一個(gè)開(kāi)放系統(Open System), 只要它與外界有接口, 就存在安全問(wèn)題, 越是商業(yè)級應用越注重安全. 安全管理涉及很廣, 大到整個(gè)網(wǎng)絡(luò )安全的設定,小到具體按鈕的訪(fǎng)問(wèn), 如果你的系統哪天出現安全問(wèn)題, 沒(méi)準追根溯源能找到機房看門(mén)老頭, 呵呵, 玩笑話(huà)略過(guò), 今天我們主要看看Drupal的用戶(hù)權限管理, 也就是訪(fǎng)問(wèn)控制系統.
權限管理的要素
我認為, 一個(gè)權限管理系統主要由以下四要素組成: 訪(fǎng)問(wèn)者, 管理對象, 操作和規則.
- 訪(fǎng)問(wèn)者: 誰(shuí)干? who. 一般來(lái)說(shuō)是人, 嚴格來(lái)說(shuō)應該叫主動(dòng)體, 這要看你的系統面向哪些用戶(hù), 一般系統人機接口,機機接口都是存在的. 反正就是那些通過(guò)你系統開(kāi)發(fā)的接口與你交互的東東.
- 管理對象: 干誰(shuí)? which. 就是被管理的東西, 比如倉庫里的糧食, 博客系統的文章, 總之, 任何有管理要求的東西. 千萬(wàn)要記住的一點(diǎn)是: 就算垃圾也是有管理要求的.
- 操作: 干什么? what. 對應具體操作, 比如寫(xiě)文章, 運糧食, 倒垃圾...
- 規則: 怎么干? how, when, where, 定義操作實(shí)施的附加條件, 比如登陸時(shí)間等.
權限管理的系統功能
可以說(shuō), 自從有了安全問(wèn)題, 大家就在圍繞這幾個(gè)要素傷腦筋, 針對各種不同的管理需求, 也出現了各種不同的權限管理的方案, 如何在安全性,操控性, 性能以及開(kāi)發(fā)復雜性間取得平衡是恒古不變的主題. 為了聚焦今天的話(huà)題, 我們主要從系統功能角度來(lái)窺視一下,看看一個(gè)權限系統到底是如何工作的.
- 首先當然權限的定義, 即識別出系統中需要進(jìn)行訪(fǎng)問(wèn)控制的要素(管理對象, 操作, 規則), 并定義成相應的權限, 這是整個(gè)權限系統的核心, 針對不同的管理粒度和管理要求, 會(huì )出現截然不同的實(shí)現方式.
- 授權, 即把權限與用戶(hù)關(guān)聯(lián), 最直接的方法是給用戶(hù)直接關(guān)聯(lián), 而最常見(jiàn)最有效的方式是使用角色(也有叫組的)
- 鑒權, 根據規則執行權限的檢查, 以實(shí)施訪(fǎng)問(wèn)控制, 看你的檢查點(diǎn)實(shí)現在哪呢, 同樣也是不同的要求有不同的實(shí)現
- 最后, 應該要能監控, 一般記日志
是不是比較清楚, 把這幾個(gè)系統功能考慮完全, 并實(shí)現好, 你的系統就安全了一半; 另一半是什么, 是你的安全意識, 天干物燥,防火防盜, 只有真正樹(shù)立安全意識, 才能有效地去應用各種安全措施, 防范危險. 不幸的是, 我們大多數人都疏予管理, 閑置, 不管不顧.
Drupal的權限管理框架
首先我們來(lái)識別系統中具備哪些要素: Drupal是一個(gè)基于web的CMS系統, 所以訪(fǎng)問(wèn)者主要局限在管理員和普通web訪(fǎng)問(wèn)用戶(hù)(User);而管理對象則是CMS中的核心--內容, 在drupal中它被抽象為節點(diǎn)(Node). (應該還會(huì )有些其他的管理對象). 操作呢? 菜單,按鈕, 在web系統里是不是都對應到頁(yè)面, 也就是內部路徑(例如: "node/1/view"), 規則沒(méi)什么特殊的: 操作時(shí)出現禁止頁(yè)面,列表中不出現無(wú)權限內容等.
Drupa采用角色來(lái)關(guān)聯(lián)用戶(hù)和操作, 每個(gè)角色是從方便系統管理角度出發(fā)來(lái)定義的一類(lèi)具備相同操作界面或行為的訪(fǎng)問(wèn)者,但它不是簡(jiǎn)單的用戶(hù)或操作的分組, 而是他們的有機結合, 形象的說(shuō)就是一組權力的代名詞或者叫Permission Scheme.Drupall針對操作是否涉及到管理對象, 設計了兩個(gè)不同的鑒權流程, 以滿(mǎn)足不同的權限管理要求.
(1)與內容無(wú)關(guān)的操作權限
權限定義
鉤子hook_perm, 定義了每個(gè)模塊的操作權限, 用操作名描述.
<?php
/**
* Implementation of hook_perm().
*/
function book_perm() {
return array(‘a(chǎn)dd content to books‘, ‘a(chǎn)dminister book outlines‘, ‘create new books‘, ‘a(chǎn)ccess printer-friendly version‘);
}
?>授權
按角色授權, 權限被分配后, 存儲在數據庫表{permission}中.
鑒權
由函數user_access進(jìn)行實(shí)際的鑒權工作, 它的參數是賬號信息與操作權限名, 返回ture或false.你可以在任何需要的地方調用該函數進(jìn)行鑒權, 但系統提供了一套默認的回調機制, 使得鑒權點(diǎn)實(shí)現簡(jiǎn)單一致.這就是菜單路由注冊函數中的access_callback參數, 該參數標明了此菜單路由需要進(jìn)行訪(fǎng)問(wèn)控制, 只有訪(fǎng)問(wèn)回調函數驗證通過(guò),才會(huì )被正確路由到對應頁(yè)面.
<?php
function forum_menu() {
$items[‘forum‘] = array(
‘title‘ => ‘Forums‘,
‘page callback‘ => ‘forum_page‘,
‘a(chǎn)ccess callback‘ => ‘_example_test_access‘, //這里指定訪(fǎng)問(wèn)驗證回調函數, 默認為hook_access()鉤子,
‘a(chǎn)ccess arguments‘ => array(‘a(chǎn)ccess content‘),
‘type‘ => MENU_SUGGESTED_ITEM,
‘file‘ => ‘forum.pages.inc‘,
);
?>鑒權鉤子, 模塊可以處理一些特殊的規則
<?php
/**
* Implementation of hook_access().
*/
function forum_access($op, $node, $account) {
switch ($op) {
case ‘create‘:
return user_access(‘create forum topics‘, $account);
case ‘update‘:
return user_access(‘edit any forum topic‘, $account) || (user_access(‘edit own forum topics‘, $account) && ($account->uid == $node->uid));
case ‘delete‘:
return user_access(‘delete any forum topic‘, $account) || (user_access(‘delete own forum topics‘, $account) && ($account->uid == $node->uid));
}
}
?>(2)節點(diǎn)訪(fǎng)問(wèn)機制(Node Access System)
drupal還提供對管理對象的訪(fǎng)問(wèn)控制--節點(diǎn)訪(fǎng)問(wèn)機制(NodeAccess System), 這是一套復雜的機制, 我還沒(méi)完全摸清. 它主要是在權限定義方面進(jìn)行了增強, 它通過(guò)定義用戶(hù),操作與節點(diǎn)的綁定, 來(lái)建立一個(gè)節點(diǎn)訪(fǎng)問(wèn)表, 這樣當需要進(jìn)行管理對象關(guān)聯(lián)鑒權時(shí), 系統會(huì )執行node_access函數,該函數會(huì )恰當地查詢(xún)節點(diǎn)訪(fǎng)問(wèn)表獲得用戶(hù)的權限, 以完成鑒權.
我們再來(lái)看看這張節點(diǎn)訪(fǎng)問(wèn)表, 用戶(hù)信息, 操作信息, 節點(diǎn)信息, OMG! m*n*P=? 如果還是按以前方式來(lái)定義, 那性能的低下可想而知,所以綜合一般的權限控制需求, Drupal僅定義了三種的原始操作: view, update, delete,而對于用戶(hù)則僅定義了一個(gè)抽象的二元組(realm, grant), 它與實(shí)際用戶(hù)間的映射由你自定義的節點(diǎn)訪(fǎng)問(wèn)控制模塊行來(lái)決定,這樣達到對用戶(hù)歸納的效果, 減小節點(diǎn)訪(fǎng)問(wèn)表紀錄的數量級.
這套機制主要通過(guò)節點(diǎn)模塊(Node Module)提供的一系列api和hook_node_grants鉤子和hook_node_access_records鉤子來(lái)實(shí)現. 我們這次知道有這套東西即可, 不鋪開(kāi)敘述.
Drupal的權限管理方法
1, 基本權限管理
盡管Drupal的權限管理機制是強大復雜的, 但其默認的基本權限管理卻非常簡(jiǎn)單, 基于角色(role)和操作權限, 把操作賦予角色, 而把角色賦予用戶(hù), 這樣用戶(hù)就能使用相應的權限. 基本權限管理粒度較粗, 只能滿(mǎn)足一般的安全需求.
2, 按內容類(lèi)型鑒權
如果我們對管理對象有更精細的管理要求, 比如我想讓A角色能訪(fǎng)問(wèn)page, B角色只能訪(fǎng)問(wèn)story, 咋辦? 基本權限管理做不到了, 那我們就擴展模塊. 內容訪(fǎng)問(wèn)模塊(Content Access )允許你對內容類(lèi)型按角色設置權限(查看, 編輯, 刪除). 其實(shí)Drupal6.2基本權限管理里也能設置按內容類(lèi)型進(jìn)行鑒權, 因為drupal把所有節點(diǎn)類(lèi)型的幾個(gè)基本操作都注冊了, 看下面這個(gè)丑陋的循環(huán), 呵呵, 這幾個(gè)也是漢化不到位的地方.
<?php
function node_perm() {
$perms = array(‘a(chǎn)dminister content types‘, ‘a(chǎn)dminister nodes‘, ‘a(chǎn)ccess content‘, ‘view revisions‘, ‘revert revisions‘, ‘delete revisions‘);
foreach (node_get_types() as $type) {
if ($type->module == ‘node‘) {
$name = check_plain($type->type);
$perms[] = ‘create ‘. $name .‘ content‘;
$perms[] = ‘delete own ‘. $name .‘ content‘;
$perms[] = ‘delete any ‘. $name .‘ content‘;
$perms[] = ‘edit own ‘. $name .‘ content‘;
$perms[] = ‘edit any ‘. $name .‘ content‘;
}
}
return $perms;
}
?>3, 按組鑒權
如果是個(gè)大公司, 有很多部門(mén), 相互間都有安全需求, 比如:
1. 能按不同的部門(mén)創(chuàng )建不同的組, 它們都能管理其私有內容
2. 組成員擁有組內的權限
3. 跨組間允許指定某些特定的權限共享
4. 匿名用戶(hù)只能訪(fǎng)問(wèn)標識為"public"的內容, 注冊用戶(hù)能訪(fǎng)問(wèn)public和Restricted, 僅組成員能訪(fǎng)問(wèn)private等
看到這么多需求, 則我們需要一個(gè)更復雜的權限管理, drupal目前有兩個(gè)擴展模塊都能提供類(lèi)似的功能:
(a) taxonomy_access modules
使用drupal的分類(lèi)模塊的基本功能, 完成以上的權限控制, 這里有英文的教程, 步驟描述較清楚.
i, 定義一個(gè)詞匯表(Groups), 用來(lái)定義組(即公司部門(mén)); 把它應用到所有內容類(lèi)型, 再添加2個(gè)條目(比如財務(wù), 研發(fā))
ii, 再定義一個(gè)詞匯表(Access), 用來(lái)定義訪(fǎng)問(wèn)級別; 同樣應用到所有內容類(lèi)型, 同時(shí)還要設置"必須"的選項, 這樣保證創(chuàng )建內容時(shí)必須選一個(gè)該
詞匯表中的條目. 加三個(gè)條目(public, Restricted, Private)
iii, 按基本權限管理的方法創(chuàng )建2個(gè)角色(財務(wù)人員, 開(kāi)發(fā)人員), 再創(chuàng )建幾個(gè)用戶(hù), 并分辨賦予對應角色(張三->財務(wù), 李四->開(kāi)發(fā))
iv, 前面都是基本管理,沒(méi)涉及到擴展模塊, 現在打開(kāi)"administer > user management > taxonomy access: permissions", 按照步驟開(kāi)始設吧, 一個(gè)組鑒權系統完成, 祝你好運.
(b) 著(zhù)名的OG
Organic Groups功能太強了, 上面的需求全部能滿(mǎn)足, 組或圈的概念是大型社區不可缺少的, 別猶豫了, 能用就用吧.
總之, drupal的權限管理機制非常靈活, 可簡(jiǎn)可繁, 每個(gè)系統都安全的需求都是不一樣的, 你們的權限管理有哪些特殊的好實(shí)現, 拿出來(lái)show繡把.

