金蝶waf2 sql语句接口说明

改造说明

前端拼接sql语句(主要是filterItems)存在SQL注入的风险,因此做本次改造以避免风险

处理方式

框架提供三种方式用于处理SQL条件子句:标准格式、自定义解析类、传递queryID

标准格式

通过前端提供的接口,将filterItems由SQL子句的格式改造成json格式。替换以前的格式传给各个filterItems(包括表格,F7,通用查询等内置控件),框架后台会自动完成解析

接口包括waf.parseSql.getFilter,waf.parseSql.mergeFilter,waf.parseSql.deleteFilter,waf.parseSql.replaceFilter,waf.parseSql.getValue。下面以id='CeUAAAAAlCnM567U'(例1)和id='CeUAAAAAlCnM567U'  and  name like ’%bob%’ (例2)为例具体说明接口的参数和用法

工具类(前端)

获取

waf.parseSql.getFilter是获取sql语句的接口,接收四个参数(keys,links,values, joins)

keys:字符串或数组,对应filter片段中的左变量(样例中即为'id'['id', 'name']

links: 字符串或数组,对应filter片段中的连接符(样例中即为'='['=', 'like']

values:字符串或数组,对应filter片段中的值(样例中即为'CeUAAAAAlCnM567U'[‘CeUAAAAAlCnM567U’,’ %bob%’]

joins:字符串,如果为样例1单语句拼接不需要传值,为样例2时需要传多个条件的连接关系(样例中即为'and'

注:若数组长度大于等于3joins需传多个连接符时格式为#1and#2or#3and#4,不支持()

合并

waf.parseSql.mergeFilter是合并两条语句的接口,接收两个参数(subjects,joins),主要是对getFilter接口中不支持小括号()的补充

    subjects:数组,元素为通过getFilter接口构造出来的filter片段

    joins:参考getFilter中说明

删除

waf.parseSql.deleteFilter是删除语句中某个片段的接口,接收两个参数(filter,args)

    filter:源sql语句(改造之后的格式)

    args:数组,长度小于等于3 。三个位置分别匹配getFilter中构造时的左变量,连接符和值,其中左变量未必传,后面两个参数如果有值则匹配否则忽略

替换

waf.parseSql.replaceFilter替换语句中某项的值,接收三个参数(filter,args1,args2),

    filter:源sql语句(改造之后的格式)

    args1:数组,长度小于等于3,分别为left(必传)和link,right(非必传)

    args2:数组,需要替换的条件,长度小于等于3,如果维持不变可在对应位置传undefined,其他均会替换

查询变量值

waf.parseSql.getValue获取某个变量的值,接收两个参数(filter,args)

    filter:源sql语句(改造之后的格式)

    args:数组,第一个参数为left(必传),第二个参数为link(若不传则默认匹配第一个left符合的)

注:1.以上前端js接口均以返回值的方式返回结果,不会修改传入的参数

    2. deleteFilterreplaceFiltergetValue三个接口使用时需要多测试避免出问题

案例

在前端构造filter时以前的通用方式是company.id='CeUAAAAAlCnM567U'  and ((billDate>='2017-08-01') and (billDate<'2017-09-01'))。

改造的方式可以把这个语句看成三部分:company.id='CeUAAAAAlCnM567U',billDate>='2017-08-01'和billDate<'2017-09-01',可以分三步完成:

  1. 调用getFilter接口获取company.id='CeUAAAAAlCnM567U'对应的格式,var orgFilter=waf.parseSql.getFilter("company.id","=","CeUAAAAAlCnM567U")
  2. 调用getFilter接口获取(billDate>='2017-08-01') and (billDate<'2017-09-01')对应的格式var  dateFilter= waf.parseSql.getFilter(["billDate","billDate"],[">=","<"],["2017-08-01","2017-09-01"],"and")或var  dateFilter= waf.parseSql.getFilter("billDate",[">=","<"],["2017-08-01","2017-09-01"],"and")

 

注:为了避免重复写前两个参数,左变量和连接符如果全部相同的话可以只传一次字符串,但是最后的值一定不能只传一个

  1. 调用mergeFilter接口连接1,2中的结果var filter= waf.parseSql. mergeFilter([orgFilter, dateFilter],”and”)获取的结果即可

 

注:以上过程由于是三个and连接实际上后两个条件的()可以忽略,因此也可以只调用一次getFilter接口:var  filter= waf.parseSql.getFilter(" company.id", "billDate","billDate"],["=",">=","<"],["CeUAAAAAlCnM567U","2017-08-01","2017-09-01"],"and")

 

自定义解析类

部分业务场景会涉及子查询或其他复杂filter拼接无法以标准格式传递,需要自定义解析类

工具类(后端)

接口com.kingdee.bos.webframework.sql.ISqlLoader

默认实现类com.kingdee.bos.webframework.sql.DefaultSqlLoader

案例

在配置页面填写完整类路径,如下图:

         自定义的解析类必须实现ISqlLoader接口,建议可以继承框架内置的解析类DefaultSqlLoader使用super的方式回调以解析标准的filter

如图中所示,接口中供业务复写的方法是getFilterItems(String filterItems,String[] queryIDs),具体实现可以参考标准产品中的com.kingdee.eas.cp.bc.dynamic.utils.BizEditSqlLoader类

传递queryID

页面初始化时,业务代码在后台构造SQL条件以参数形式传到前端页面,页面上再设置到各个控件(表格,F7,通用查询)或在js代码中使用。这种场景采用后台存储SQL,前后端交互只传递queryID的方式来处理

 

工具类(后端)

工具类com.kingdee.bos.webframework.sql.SqlUtils

生成queryID

SqlUtils. getIdByFilter(String filter,HttpServletRequest request)

filter为后台拼接的SQL子句,调用该接口后可生成queryID

还原SQL子句

SqlUtils.getFilterById(String id,HttpServletRequest request)

id为queryID,调用该接口获得对应的SQL子句

案例

在后台调用SqlUtils.getIdByFilter(String filter,HttpServletRequest request)接口获取queryID,将queryID传递到前端,赋值给相应框架控件的queryID属性,框架后台解析filter时类自动取出queryID对应的filter进行拼接。如果是以2中自定义解析类的方式也可以自行调用SqlUtils的getFilterById(String id,HttpServletRequest request)方法获取filter完成拼接。

 

注:1.针对部分反应SqlUtils方法中request中接口无法获取的问题,在web工程项目中可以从两个地方拿到:各handlerevent参数中或controllerspring注入的request;通过(HttpServletRequest) com.kingdee.bos.webframework.context.WafContext.getInstance().getRequest()方式获取;

         2.复杂查询的情况在web列表页面中除配置自定义解析类的方式也可以配置页面listdata的前插入事件,从request中取出filterItems经过自定义处理之后把解析的结果放到modelMap中(键也为filterItems),走框架解析时会优先取modelMap处理过的条件

补充说明

扩展使用

框架目前只内置了对filterItems的处理,同时后台检测敏感字符时也只针对了filterItems参数,如果具体业务有其他参数需求可以修改server\deploy\easweb.ear\eas_web.war\WEB-INF\properties\waf2.properties文件中checkParams参数添加需要自动检测的参数,修改checkKeys参数中需要额外过滤出现的关键字符(此参数中出现的#表明过滤的是关键字后接任意个控件,即以其他字符串形式出现的不被拦截,配置参数时也需避免以关键字结尾)

兼容模式

考虑到部分产品改造时间会比较长,框架提供了兼容模式,支持改造后的标准格式和改造前的格式混用。server\deploy\easweb.ear\eas_web.war\WEB-INF\properties\waf2.properties中compatible的值为true时开启兼容模式(默认为true)。注意,兼容模式中sql的左变量和值中不能出现{和},否则解析会出错。并且开启时只是在解析会分别解析两种格式,仍然不能对改造之后的格式进行破坏操作(例如substring之类的截取操作)

调试

调试时会出现sql语句不直观,queryID对应的条件无法查看等问题。框架提供了工具用于查询filterItems、queryID、自定义解析类,工具地址如下:

http://ip:port/easweb/dynamicPage.do?event=initialize&method=doEvent&uipk=com.kingdee.eas.webDev.webDevTools&waf2skin=easbase&inwafpage=false&debug=true

其中filterItems,queryID即为相应参数不赘述,uipk是针对配置了自定义解析类的页面需要加上。结果中第一个boolean类型为能否通过关键字过滤检测,剩下部分为sql在后台得到的翻译结果。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书耳朵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值