第六章
细粒度数据操作权限
很多系统对于黑客不堪一击。请看这样的示例:
1.
前台展现客户能查看的客户数据,而且用户能删除的客户数据,就是前台展现出来的数据;
2.
当用户选择某个用户,点击删除按钮,后台执行删除操作。
比如,请求后台删除的url是:http://www.test.com/crm/customer.do?id=3
假设,id=13的客户在前台不显示(因为当前用户没有对该客户数据有删除权限),但用户输入http://www.test.com/crm/customer.do?id=13
显然id=13的客户将被删除掉。
有开发者建议采用id值不要使用自增长型,而改用其他型,比如hashcode等。这也不大合适,可以使用爬虫轻松地将漏洞爬出来。
显然,仅仅通过界面层次控制数据级权限是不够的。
解决方案
数据级防火墙
显然,需要为业务系统构建一道数据级防火墙。该防火墙能够判断当前用户对请求的数据,是否有操作权限。如果没有操作权限,告知业务系统,且告知拒绝理由。
防火墙位置
后台业务方法被执行前,需要做个权限检查。检查通过后,才执行该操作,否则不予执行。
这种注入模式有2种,1,硬编码注入;2,AOP方法拦截。
硬编码注入,类似这样:
…
if( SecurityService.permit( user, customer, Privilege.DELETE_CUSTOMER ) ) {
customerService.delete( customer );
} else {
…
// 对该客户没有删除权限,转移到提示界面
}
…
AOP方法拦截,通过给业务方法annotation签名。当该方法被执行时,自动触发权限判断逻辑。
public interface CustomerService {
/**
* @security id=DELETE_CUSTOMER
public void delete( Customer customer, User user );
}
权限逻辑
大多业务系统,采用if
else逻辑判断,判定用户是否具有对某数据的操作权限。
这种细粒度的权限逻辑,无法或者说非常难使用某种模型来自动处理。因此大多系统采取硬编码模式实现权限逻辑。
本章介绍怎样使用Metadmin来管理权限逻辑。
如果使用Metadmin
以下演示来自metadmin下载包里面包含的演示示例,可以在www.metadmin.com 下载Metadmin安装程序包。
Metadmin不通过编程,而是通过设计器快速设计出权限逻辑,并可在线测试权限逻辑。
怎样与系统集成
MetadminService类,提供如下方法:
static Decision
|
permit (int privilegeId, User user,
java.lang.Object businessData, java.util.Map context)
评估决策授权策略,返回决策结果。
|
表示对于privilegeId操作,user对于businessData业务数据是否有操作权限。context表示权限判定需要的业务数据,可以为null。
WebMetadminService类,提供如下方法:
static boolean
|
permit (HttpServletRequest req,
int privilegeId, java.lang.Object businessObject)
评估决策授权策略,返回决策结果。
|
static boolean
|
permit (HttpServletRequest req,
int privilegeId, java.lang.Object businessObject,
java.util.Map context)
评估决策授权策略,返回决策结果。
|
WebMetadminService为MetadminService为Web程序封装,从HttpServletRequest里面取出user,而不用显式地传值。
完整JAVADOC请浏览:http://www.metadmin.com/doc/javadoc/index.html
示例程序,对删除员工进行权限判定代码如下:
if (WebMetadminService.permit(req, Privilege.DELETE_EMPLOYEE,
employee)) {
employeeManager.deleteEmployee(id);
}
employee对象,是根据前台传入id参数从数据库查询出来的员工对象。
权限逻辑设置
上章例子设置:总公司用户能查询所有员工;分公司用户能查询本分公司及下属营业部员工;营业部员工能查询本营业部员工。
本例将员工删除权限修改一下:所有用户只能删除自己所在机构的员工,也就是总公司用户只能删除总公司员工;分公司用户只能删除分公司员工;营业部用户只能删除营业部员工。
Metadmin对于这样的权限逻辑,只要新建“所有用户”用户分类,及“用户所在机构员工”业务数据分类,然后将该2种分类配对设置该“删除员工”权限即可。
首先,创建“所有用户”用户分类,打开设计器:http://localhost:8080/mydemo/metadmin/designer
1.
在用户分类栏,新建分类,输入名称为“所有用户”;
2.
创建固定值a,设置其值为1;
3.
在表达式定义处,定义Binary表达式“a=a”。
这样,所有用户都会满足该条件。
然后,创建“用户所在机构员工”业务数据分类,打开设计器:http://localhost:8080/mydemo/metadmin/designer
1.
在业务数据分类栏,新建分类,输入名称为“用户所在机构员工”;
2.
创建用户属性变量“userCompanyId”,其值等于用户的companyId属性;
3.
创建业务数据变量“businessDataCompanyId”,其值等于Employee对象的companyId属性;
4.
在表达式定义处,定义Binary表达式userCompanyId==businessDataCompanyId。
这样,只有当user对象和employee对象的companyId属性相等时,数据才属于该业务数据分类。如图示:
然后,将该分类配对设置给删除员工权限。如图示:
至此,权限逻辑设置完毕。业务代码里面集成的权限判断,将按照该逻辑执行。当权限判断逻辑发生变化,只要打开设计器重新设计权限逻辑即可。不需要修改代码,重新发布系统。
posted on 2009-06-23 09:55
细粒度权限管理 阅读(3463)
评论(3) 编辑 收藏