框架级防止用户任意输入url参数,查看别人单据,或其他不该自己看到信息
工作流实例检查,看当前用户是否在该实例的审批列表以及通知列表里面
-
1.在../WEB-INF/aurora.feature/service-listener.config中添加<participant class="aurora.security.AccessCheck"/>
<participant-manager xmlns="uncertain.event">
<participant-list category="service">
...
<participant class="aurora.security.AccessCheck"/>
</participant-list>
</participant-manager>
-
2.在../WEB-INF/aurora.feature/service-procedure.config中<p:procedure name="pre-service">节点末尾添加<p:action Name="AccessCheck" />
<?xml version="1.0" encoding="UTF-8"?>
<p:procedure-registry xmlns:t="aurora.application.action" xmlns:a="http://www.aurora-framework.org/application"
xmlns:p="uncertain.proc">
<p:procedures>
<p:procedure name="pre-service">
<p:set field="@success" value="true"/>
<t:session-copy/>
<p:switch test="@is_autocrud_service">
<p:case Value="true">
<t:bm-access-check errorMessage="没有权限访问,或登录已失效"/>
</p:case>
<p:case>
<t:resource-access-check resultPath="/access-check/@status_code"
errorMessage="登录已失效,请重新登录"/>
</p:case>
</p:switch>
<t:check-dispatch dispatchUrl="${/request/@context_path}/error_screen_unregistered.screen"
field="/access-check/@status_code" message="页面没有注册" value="unregistered"/>
<t:check-dispatch dispatchUrl="${/request/@context_path}/error_screen_unauthorized.screen"
field="/access-check/@status_code" message="没有权限访问指定的页面" value="unauthorized"/>
<t:check-dispatch dispatchUrl="${/request/@context_path}/error_session_expired.screen"
field="/access-check/@status_code" message="登录已失效,请重新登录" value="login_required"/>
<p:action Name="AccessCheck" />
</p:procedure>
<p:procedure name="application-start">
<p:invoke procedure="init.load_system_service"/>
<p:invoke procedure="init.load_priviledge_check_data"/>
</p:procedure>
<p:procedure name="session-destroy">
<a:model-update model="sys.sys_expire_session"/>
</p:procedure>
</p:procedures>
</p:procedure-registry>
-
3.通过配置文件../WEB-INF/aurora.security/access-check-rule.config,集中配置所有的参数校验规则:
<?xml version="1.0" encoding="UTF-8"?>
<s:access-check-rule-config xmlns:s="aurora.security">
<access-check-rules>
<s:access-check-rule name="wflInstanceCheck" description="工作流实例检查,看当前用户是否在该实例的审批列表以及通知列表里面"
checkBM="security.wfl_instance_permission_check" checkField="@IS_VALID" successValue="Y" />
<s:access-check-rule name="financeCheck" description="财务人员查看权限"checkBM="security.finance_permission_check"
checkField="@IS_VALID" successValue="Y"/>
</access-check-rules>
</s:access-check-rule-config>
Table 1. access-check-rule标记属性
属性 | 描述 |
---|
name | 验证规则名称 |
description | 验证规则描述 |
checkBM | 指定的验证BM |
checkField | 校验BM返回的结果 |
successValue | 验证成功参考值,和否和checkField一致 |
-
4.定义验证BM(如security.wfl_instance_permission_check):
<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm">
<bm:operations>
<bm:operation name="query">
<bm:query-sql>
select 'Y' as IS_VALID from dual
where exists (
select r.instance_id from wfl_notification_record r
where r.instance_id = ${/parameter/@instance_id} and r.user_id = ${/session/@user_id}
union all
select t.instance_id from wfl_instance_node_recipient t
where t.instance_id = ${/parameter/@instance_id} and t.user_id = ${/session/@user_id}
)
</bm:query-sql>
</bm:operation>
</bm:operations>
<bm:fields>
<bm:field name="IS_VALID"/>
</bm:fields>
</bm:model>
-
5.在所有需要验证的screen/svc中,设置tag,说明要进行哪些检查:
<?xml version="1.0" encoding="UTF-8"?>
<screen>
<access-check name="wflInstanceCheck" />
<init-procedure>
...
</init-procedure>
<view>
...
</view>
</screen>
-
1、关于工作流审批嵌入界面
对于工作流审批界面直接嵌入的screen,因为是采用screen-include方式,所以没有安全性问题。嵌入的单据界面,参数是在server端解析传递的,不会被客户端篡改。整个安全性验证是以工作流的待审批记录id为依据,只要客户端传递的审批记录id合法就OK。但是,要防止用户获得工作流嵌入的显示页面名称,直接敲地址参数访问。一般只要这类界面对应的功能没有直接被分配给任何角色就好了。
But,如果审批界面中还要点个链接,弹出一个新页面,这个新页面就要做参数验证了。比如,报销单审批界面中,点按钮弹出分配行明细界面,这个界面有可能被用户看到url和参数,所以就要做参数验证。因为工作流可能会被配置成各种可能的用户参与审批,所以直接应用上面那种业务规则往往不行。比如,张三审批李四的报销单,张三既不是分公司财务,也不是总公司财务,但对于这一单来说,他有权限查看。
这时候,可以考虑写一个专为审批查看使用的screen,参数为工作流instance_id+报销单行id,验证规则为当前用户有权限审批参数指定的工作流记录。然后,通过sql查出合法的line_id记录,例如
select line_id from exp_lines where line_id=${/parameter/@line_id}
and head_id =
根据工作流instance_id获取单据头id。如果客户伪造一个不该他审批的line_id作为参数传递,上面这段sql不会有记录。最后,用
<screen-include
screen="查看分配行.screen?line_id=${/model/check-record/@line_id}">包含一个现成的分配行查看界面。这样可以绕过分配行查看原来的业务规则(因为参数验证是以screen/svc为单位进行,不会对screen-include包含的界面再进一步检查),重用现有界面,又能保证安全性。
-
2、什么时候用参数验证,什么时候用BM的data-filter
BM的data-filter可以施加一些强制性的where限制,也可以起到类似的效果。如果所有查看页面所需要的数据,其来源BM都通过派生获得了这种安全性where条件限制,那么就能保证传入非法参数时查不出记录,这时候直接用BM的data-filter就可以了。
如果当初设计BM的时候没有考虑周全,或者screen/svc里面不是每一个BM操作对应的BM都有这种安全性防范,或者验证逻辑很复杂,不适合直接写成where表达式,那就考虑用access-check特性。
Comments
0 Responses to the article暂时没有评论。