记录级别安全在代码中执行了吗?
我最近碰到了一个关于记录级别安全的异常问题,似乎以前并没有相关的文档记录。因此我想与您分享一下。
情况是有一个emplId=”RLS”的员工,同时有一个配置了记录级别安全的用户组,该用户组允许成员访问除了“RLS”之外的所有员工。现在该组中的一个用户运行了一张报表,其fetch()方法如下:
public boolean fetch()
{
boolean ret = true;
EmplTable emplTable;
;
//emplTable.recordLevelSecurity(false);
select firstonly emplTable where emplTable.EmplId == 'RLS';
return ret;
}
结果应该是什么? emplTable表的缓冲区应该被填充吗?记录级别安全(RLS)并没有在代码中执行,是吗?非也!
尽管大多数情况下RLS并不会在代码中执行,却有一些例外:表单控件上的reportRun.fetch(), reportRun.send() 和 lookup() 方法.
AX内核所做的是在调用这些方法之前对整个当前的X++流开启RLS,并且在方法返回时关闭它。其效果就是这些方法中的任何代码或者任何调用这些方法的代码默认都会开启RLS。
在上述代码中如果我们取消注释emplTable.recordLevelSecurity(false)行,缓冲区就会绕开RLS并成功填充。
还有一些其它的奇怪表现 : 如果您打印emplTable.recordLevelSecurity() 方法的结果,系统会显示缓冲区的RLS并没有开启 ―― 这是因为RLS是在针对整个X++流的更高级别开启的,并非直接设置了缓冲区属性。
另一个奇怪表现是如果您从用户选项-〉开发标签-〉数据库追踪选项中打开追踪,您会发现在这种情况下针对表的调用的RLS已经开启了。这个是正确的,因为追踪是在内核层检测访问表时RLS是否真正开启――事实就是如此。
AX2012中该问题不再出现――安全框架和报表都已重写。
原文地址: