17 April 2005
This post may be outdated due to it was written on 2005. The links may be broken. The code may be not working anymore. Leave comments if needed.

描述

很多地方我们都会运用到权限控制,比如 *nix 的文件读写,CMS 系统的文章录入审核,和 BBS 系统的斑竹,总斑竹,坛主等等。

这篇文章用途不大,可看可不看。我自己都觉得可以删掉。

下面讲的都是及其简单的情况下,实际的应用可能比这复杂得多。

先假设一些东西以方便我的书写:

  • 四个人 Member1, Member2, Member3, Member4
  • 四个操作:create, edit, list, delete
  • Member1 可以 create, edit, list, delete
  • Member2 可以 create, edit, list
  • Member3 可以 edit, list
  • Member4 只能 list

实现权限控制的方法有好多种:

  • 一种是针对人,某人有某操作权限。数据一般写到 member 文件或 user 数据库里面
Member3.dat
privilege = edit,list

当然 privilege 可以用其他方式来表达,比如用0和1做开关来表达,privilege = 0110;或者用2的几次方来表达

  • 另一种是针对操作,某操作可以有哪些人来执行。数据一般保存在操作文件里
create.dat
members = Member1,Member2

当 Member 变得很多时,不同 Member 可能有同样的操作权限,如此再一对一的话就会产生数据冗长。不可避免将引用 组/Group 的概念。将拥有同样权限的人划入同一组,一组对应某一类权限。

上面的假设变为:

  • N 个人 Member1, Member2, ... MemberN
  • M 个组 Group1, Group2, ... GroupM
  • Group1 成员有 Member1, Member7, ...
  • ...
  • Group1 对应操作 create,list,edit,delete
  • ...

一个没什么实际用途的代码如下:

#Member1.dat
#groups = Group1,Group3

#create.pl
#!/usr/bin/perl
use Data::ACL;
use Set::NestedGroups;

my $user = $q->param('user'); # get the username, such as Member1
open(FH, "$user.dat");
... # get $my_groups or $user{$user}{'groups'} = 'Group1,Group3';

my $groups = Set::NestedGroups->new;
foreach (split(/\,/, $my_groups)) {
    $groups->add( $user, $_ );
}

my $acl = Data::ACL->new($groups);

my $acl_create = $acl->Realm('create');
$acl_create->Deny( 'all' );
$acl_create->Allow('Group1');
$acl_create->Allow('Group2');

my $acl_edit = $acl->Realm('edit');
$acl_edit->Deny( 'all' );
$acl_edit->Allow('Group2');

if ($acl->IsAuthorized( $user, 'create' )) {
    # do create stuff. this member can do it
} else {
    print 'Access(create) Denied!';
}

if ($acl->IsAuthorized( $user, 'edit' )) {
    # do edit stuff, this member cann't do it
} else {
    print 'Access(edit) Denied!';
}

真正的实际应用比这情况复杂得多。而且得考虑很多东西,比如效率,组与组之间的关系(组继承等)。打算有空举个实际例子应用下。



blog comments powered by Disqus