代码改变世界

关于Web应用程序安全的思考(三)

2007-10-03 20:04  Jacky_Xu  阅读(185)  评论(0编辑  收藏  举报
应用程序的安全管控包括管控的时机和方法两个方面﹐即在哪里或什么时候进行管控﹐和使用什么依据进行权限管控。

在前几篇中﹐我提到在web应用程序进行安全管控的时机是在每次Request到达真正的应用程序之前进行﹐现在在总结一下其特点﹕

1.这种方式不会出现未管控的死角(每次请求都会进行﹐每次动作都会经过验证)﹐并且抽象出web应用程序的本质(所有的服务器端程序都是在客户端request)﹐这样也就可以与业务系统解耦﹐单独设计了。

2.在每次执行前就进行权限管控应该更安全﹐因为用户在没有授权的情况下是接触不到真正的业务程序。

 

当然﹐进行安全管控的时机还包括在程序执行时的UI阶段﹐商业逻辑调用阶段以及数据库操作阶段等地方进行﹐其实它们本质上都一样(当然数据库操作阶段有待商榷﹐因为并不是系统所有的动作都会映射到数据库)﹐但是在web应用程序中﹐相对于我讲的那种方式﹐他们都有一些缺点﹐如﹕不容易抽象﹐可能会有管控死角和系统耦合度高等。

 

但是对于这三种方案﹐也有其自己的适用背景﹕

1.      数据库﹕适用于有多个系统(甚至不同的语言开发的系统)存取同一个数据库的情景﹐而为了统一管理数据存取权限﹐而在数据库层做的权限管控。

2.      逻辑层﹕适合于既有web作为UI﹐又有诸如smart clientwinformconsole甚至通过.net remoting作为调用方的系统。

3.      UI层﹕至于UI层﹐我想就可能只适合于系统较小或权限较简单的情况了。

 

讲了权限管控的时机之后﹐接下来再来讨论一下安全管控的方法了。

 

安全管控的方法其实就是权限管控了。

 

而权限管控就是判断当前用户是否有当前操作对象的权限。即﹕判断当前操作的是什么对象﹐当前用户是谁﹐当前用户是否有这个对象的对应。

 

权限管控的程序代码看起来就像这个样子﹕

 

 

1:当前用户 = GetCurrentUser()

2:当前对象 = GetCurrentRight()

3:Bool right_flag = HasRight(当前用户,当前对象)

If(
!right_flag)

{

   
4:没有权限

   
return

}

程序继续

 

这里最困难的地方应该就是当前对象(即以什么来作为权限判断的客体)的分类标准了﹐我基本上看过这几种﹕

1.以数据库中特定数据表的增﹐删﹐改﹐查作为管控对象的

2.以逻辑类的方法作为管控对象的

 

无意讨论上述两种标准的优劣﹐而只提出我的观点﹕

 

我认为﹕对于任何一个系统﹐它的权限本质上就是按用户的需求实现的系统功能

 

如一个订单管理系统实现的功能可能有﹕下单﹐审核﹐出库﹐订单打印﹐出库单打印等。

 

因此在判断当前对象时﹐只要认定当前的动作是属性哪一种系统功能即可

 

如﹕用户单击提交订单按钮﹐则是属于下单功能

用户访问订单审核页面﹐这是属于审核功能

用户单击审核按钮﹐这也是属于审核功能

用户访问打印程序﹐根据type = 订单﹐我可以判断这是属性订单打印功能﹐根据 type = 出库﹐我可以判断这是出库单打印功能。

 

顺便再提一下这种情况﹕

张三只能审核A部门的订单

李四可以审核A部门﹐B部门的订单

王二可以审核所有部门的订单

 

其实我们将这种需求抽象为数据权限﹐这部分功能会以hardcode方式编写在当前程序中﹐当前程序在访问待审核的订单数据时﹐是在代码中将其权限部门的数据传入而来得到的﹐因为用户提出的這個需求审核功能﹐实际上是审核其权限下部门的订单的功能﹐所以这时要区分用户真正业务需求与非业务的需求。

再举个例子﹐如果用户又告诉我们只有部门主管以上的用户可以审核订单﹐这时我们就认为它是非业务需求﹐我们在设计和开发业务系统时不考虑这一点﹐而在运行时帮他或告诉他如何分配部门主管以上的用户的审核订单的权限。

 还有一点﹐在我们的权限设计中﹐我们的客体只有一个﹐即系统功能﹐而没有对客体的操作进行判断﹐如﹕

张三 订单   删除

李四 订单   审核

这样的情况﹐我们会将它抽象为﹕删除订单和审核订单2个系统功能