JOOQ中的行级安全性实现
我想使用JOOQ库在Java中实现oracle行级安全类function
以下是JOOQ查询代码的示例:
Result result = dslContext.select().from(Employee.EMPLOYEE).fetch();
上面的代码将生成如下SQL:
select [dbo].[Employee].Id,... from [dbo].[Employee]
我想添加一个where子句来过滤特定于用户安全性的数据,如下所示:
select [dbo].[Employee].Id,... from [dbo].[Employee] WHERE [dbo].[Employee].Security IN (1,2)
显式谓词
除非我遗漏了一些不错的SQL Serverfunction,其中行/记录包含一个名为.Security
的伪列来实现行级安全性,你应该能够简单地写
dslContext.select() .from(EMPLOYEE) .where(EMPLOYEE.SECURITY.in(1, 2)) .fetch();
有关jOOQ谓词构建的更多信息,请参阅此处的手册:
尤其是IN
谓词:
使用jOOQ的ExecuteListener的一般解决方案
鉴于您的意见,您正在寻找一种通用方法来修补所有SQL语句的附加谓词,无论特定程序员输入什么。
您可以使用jOOQ执行此操作,但请注意,如果程序员绕过jOOQ,这只会帮助您强制执行谓词,而不是保证它。 你可以做的是设置一个ExecuteListener
,拦截renderStart()
事件,以便修补/替换正在执行的查询。 这些方面的东西:
@Override public void renderStart(ExecuteContext ctx) { if (ctx.query() instanceof Select) { // Operate on jOOQ's internal query model SelectQuery> select = null; // Check if the query was constructed using the "model" API if (ctx.query() instanceof SelectQuery) { select = (SelectQuery>) ctx.query(); } // Check if the query was constructed using the DSL API else if (ctx.query() instanceof SelectFinalStep) { select = ((SelectFinalStep>) ctx.query()).getQuery(); } if (select != null) { // Use a more appropriate predicate expression // to form more generic predicates which work on all tables select.addConditions(EMPLOYEE.SECURITY.in(1, 2)); } } }
当然,上面还有改进的余地。 随意讨论用户组的用例
使用jOOQ的VisitListener的一般解决方案
如果你愿意深入研究jOOQ的内部,你也可以尝试实现一个VisitListener
并实际转换jOOQ的查询AST表示。 这在此记录:
使用视图的一般解决方
虽然上面的工作,我个人建议您使用视图,并隐藏开发人员的实际表。 例:
CREATE VIEW v_employee AS SELECT a, b, c, ... FROM t_employee WHERE t_employee.security in (1, 2)
通过适当的授权,您可以隐藏开发人员的表格,确保他们只使用所需谓词的视图始终到位
- Liferay ClassNotFoundException:DLFileEntryImpl
- 如何将AT命令的输出转换为java中的字符串?
- 在jenkins构建下以无头模式运行cucumber-jvm selenium测试用例时出错
- java – google guava缓存invalidateAll()和cleanUp()之间的区别
- 是否可以将普通套接字更改为SSLSocket?
- 为什么我不能在Java中的switch语句中使用’continue’?
- java.lang.NoSuchMethodError:javax.persistence.OneToMany.orphanRemoval()
- JButton列之间的间距
- 在JFrame中切换JPanel