1 需求
目前我做的这个项目的权限的要求可以归结为以下几点:
- 用户是基于角色的。每个用户属于,且仅属于一个角色。
- 系统中存在至少一个超级用户,且该用户具有所有权限。只有超级用户具有用户管理权限。
- 超级用户可以仅仅针对某一个人定义权限。
- 对于权限的判断,有以下两种基本形式,其它形式是这两种形式的演化:
- 不含参权限。例如用户是否具有添加用户、管理文章分类的权限等。
- 含参权限。例如用户是否具有某一个类别的文章的管理权限,这里某一个类别即为参数。
2 类
其中:
- UserRole表示用户角色、User表示用户。
- User含有对UserRole的引用,表示用户属于哪个角色。
- UserRole和User都拥有一个权限Power,即拥有一个Power的引用。
- Power真正处理权限的判断,UserRole和User的HasPower方法最终委托给Power的HasPower方法。
- PowerItem描述的是系统中的权限项目。
3 调用
不含参权限判断为:
User user = getUser();
bool isUserHasArticleClassManagePower = user.HasPower(PowerItem.ArticleClassManage);
含参权限判断为
User user = getUser();
bool isUserHasArticlePower = user.HasPower(PowerItem.ArticleManage, someArticleClassID);
设置用户和用户组具有某一个权限为:
User user = getUser();
UserRole userRole = getUserRole();
Power power = user.Power; //Or power = userRole.Power;
power.SetPower(PowerItem.ArticleClassManage);
power.SetPower(PowerItem.ArticleManage, someAricleClassID);
清除用户或用户组的某一个权限为:
User user = getUser();
UserRole userRole = getUserRole();
Power power = user.Power; //Or power = userRole.Power;
power.ClearPower(PowerItem.ArticleClassManage);
power.ClearPower(PowerItem.ArticleManage, someAricleClassID);
4 实现
User的HasPower方法最终的实现如下:
1: /// <summary>
2: /// 判断是否具有某一项权限
3: /// </summary>
4: /// <param name="powerType">权限类别</param>
5: /// <param name="param">判断所需要的参数</param>
6: /// <returns>是否具有该权限</returns>
7: public bool HasPower(PowerItem powerType, object param)
8: {
9: //超级用户拥有所有权限
10: if (_IsSuper) return true;
11:
12: //如果该用户是自定义权限,则使用自身的权限进行判断,
13: //否则,使用对应角色的权限进行判断
14: if (_IsCustomPower)
15: return Power.HasPower(powerType, param);
16: else
17: return _UserRole.Entity.HasPower(powerType, param);
18: }
UserRole的HasPower方法比较简单,仅仅是委托给其Power成员的HasPower方法:
public bool HasPower(PowerItem powerType, object param) { return this.Power.HasPower(powerType, param); }
Power类是判断权限的核心。
其成员Powers以"0,1,1,1"的方式保存了所有的权限。权限在该序列中的位置对应其权限项目的枚举值。例如PowerItem.ArticleClassManage的值是1,则序列"0,1,1,1"的第二个数(下标从零开始),表示是否具有ArticleClassManage权限。
对于含参的权限。例如PowerItem.ArticleManage,有一个成员AritcleClasses保存了所有判定为真的参数。如果该成员的值为“1,2,5”,则说明该用户或该角色具有ID为1,2,5的这三个文章分类的管理权限。
其HasPower方法为:
1: public bool HasPower(PowerItem powerType, object param)
2: {
3: if (!hasPower(powerType)) return false;
4:
5: //根据参数进行判断
6: switch (powerType)
7: {
8: case PowerItem.ArticleManage:
9: return hasPower(_AritcleClass, param);
10: default:
11: return true;
12: }
13: }
至于其中私有方法的细节,可以参考代码。