我想动态过滤 JDBI 查询。
参数列表通过 REST 从 UI 传递,例如
http://localhost/things?foo=bar&baz=taz
http://localhost/things?foo=buz
它(笨拙地)构建为(Jersey @Context UriInfo::getQueryParameters -> StringBuilder),如下所示:
WHERE foo=bar AND baz=taz
并传递给 JDBI,如下所示:
@UseStringTemplate3StatementLocator
public interface ThingDAO {
@SqlQuery("SELECT * FROM things <where>)
List<Thing> findThingsWhere(@Define("where") String where);
}
据我了解,当前的实现很容易受到 SQL 注入的攻击。
显然我可以清理列名,但不能清理值。1
必须有一种更优雅且防 SQL 注入的方法来执行此操作。
灵感来自让·伯纳德我想出了这个:
public class WhereClause {
public HashMap<String, String> queryValues; // [<"foo","bar">, <"baz","taz">]
public String preparedString; // "WHERE foo=:foo AND bar=:baz"
}
通过自定义 Binder 绑定BindWhereClause
:
@BindingAnnotation(BindWhereClause.WhereClauseBinderFactory.class)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER})
public @interface BindWhereClause {
class WhereClauseBinderFactory implements BinderFactory {
public Binder build(Annotation annotation) {
return new Binder<BindWhereClause, WhereClause>() {
public void bind(SQLStatement q, BindWhereClause bind, WhereClause clause) {
clause.queryValues
.keySet()
.forEach(s -> q.bind(s, clause.queryValues.get(s)));
}
};
}
}
}
和一个组合@Define
and @Bind
:
@UseStringTemplate3StatementLocator
public interface ThingDAO {
@SqlQuery("SELECT * FROM things <where>")
List<Thing> findThingsWhere(@Define("where") String where,
@BindWhereClause() WhereClause whereClause);
}
这应该是防注入的。 (是吗?)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)