我正在使用GWT / RequestFactory以及一组有关权限的客户要求。让我解释一个基本的例子:
每个用户都被分配到一家公司。每个用户都应该能够编辑公司的核心数据 - 但仅限于联系信息,网站等。如果用户具有特定权限XY,则只能更改与BIC / SWIFT,IBAN,公司名称等安全相关的数据。
到目前为止,在客户端我可以检查权限并禁用那些不允许用户编辑的字段。但是,在服务器端确保未经许可未设置这些字段的最优雅方法是什么?
我的问题是我无法跟踪服务器端的更改。在每个setter上都有@PreAuthorize也不是一个选项,因为它会在每个实体的授权大屠杀中结束。
目前我正在采取一种解决方法:保护/依赖于给定权限的每个字段都作为参数传递给entity-method,并从代理中排除。这样,无法使用代理设置值,如果用户有权限,我可以检查我的服务器代码。如果没有,没有任何反应。如果用户具有权限,我手动设置值。但是这会产生大量的样板代码和丑陋的方法签名,因为传递给方法的值的数量可能会变大。
我希望你理解我的问题。我期待着您的意见和建议。先感谢您。
答案 0 :(得分:0)
嗯,你可以收到很多答案(彼此不同),而且所有答案都是正确的,所以,最后是你的电话。等待别人的答案。我将为您提供我遵循的方法(并且它工作得非常好)。 :d
在我看来,服务器应尽量少做,所以保留允许修改服务器上每个参数的逻辑我认为它不是一个可扩展的解决方案(如果你的系统有1M用户同时修改所有内容时间,你的服务器能流利吗?)。我更喜欢让客户做这项工作(如Roomba:D)。
为解决这个问题,我们在系统中实施了一个访问控制列表解决方案。您可以在每个用户实体的数据库中存储具有已授予权限的列表。因此,当该信息到达客户端时(例如,在用户登录之后),您可以获取它们,并显示他/她允许修改的字段。
类似的东西:
if (canModifyPersonalDetails(user.getAcls(), ...) ) {
//show labels ...
}
if (canModifyBankDetails(user.getAcls(), ...) ) {
//show labels
}
你无法避免服务器调用登录,所以发送额外信息并不是什么大事(想想ACL可能是简单的整数列表0表示个人详细信息,1银行详细信息....)。< / p>
如果您正在处理非常受损的信息并且您更喜欢在服务器上执行某些操作,那么可能我会设置安全级别,当您持久/更新代理时,我会这样做做类似的事情:
if (isAllowForPersonalDetails(user.getSecurityCode()) {
//update the modified personal details
}
if (isAllowForBankDetails(user.getSecurityCode()) {
//update the modified bank details
}
user.update();
我非常喜欢明确的用户界面,并且非常喜欢让服务器尽可能免费,所以我更喜欢第一个选项。但是如果你有修改db中用户实体的约束,或者你不想修改你的视图或任何具有安全性的约束,那么第二个选项对你来说可能是最好的选择。
希望有所帮助!