6

应用程序

我需要实现一个可供不同用户使用的网络应用程序。每个用户对不同的表有不同的权限,例如

  • 用户 A 可以从表中看到字段“名称”和“地址”Student
  • 用户 B 可以从表中看到字段“姓名”和“电话号码”,但看不到“地址”Student
  • 用户 C 可以查看和修改上述所有字段

  • 我将在 UI 级别有一些东西来限制某些访问,例如为无权修改条目的用户隐藏“编辑”按钮。但是,我认为我应该在较低级别(也许在数据库级别?)只是为了确保数据安全。


    问题

    我正在为我的应用程序使用 Hibernate、JBoss、DB2 和 Struts。我想我应该使用某种 JBoss LoginModule,它使用用户/密码/角色对数据库进行用户身份验证(但我可能错了(?))。我做了一些研究并提出了以下选项,但似乎没有一个适合我的情况。我认为这是多用户 Web 应用程序中非常常见的数据访问问题。有人可以指出我正确的方向吗?先感谢您!

    1. hibernate.cfg.xml在JACC 事件监听器中使用“grant”标签。这可以对所有休眠实体设置“插入”“更新”“读取”权限。但是,如果我需要更精细的控制怎么办?我需要对某些字段而不是整个对象设置权限。http://www.hibernate.org/hib_docs/v3/reference/en-US/html/objectstate-decl-security.html

    2. 限制每个 ejb 的 getter/setter 方法的权限。如果我理解正确,这需要为每个用户配置文件手动配置每个 bean,这对我来说似乎不现实。 EJB 方法权限

    3. 对 DAO 进行编码以检查用户权限。滚动我自己的实用函数,每次调用特定的 DAO 方法时检查一个巨大的权限表,以确定登录用户是否可以执行该操作。

    4. 在 Hibernate 中使用“拦截器”和“事件”。为每个类定义特定的“onLoad”、“onSaveorUpdate”等事件和拦截器。在这种情况下,我可以为各个字段指定权限级别吗?http://www.hibernate.org/hib_docs/v3/reference/en-US/html/objectstate-events.html

    我可能是对着错误的树吠叫。以上所有似乎都是劳动密集型的,不是很聪明。以上选项都没有为我提供在运行时更改用户权限的编程方式,当管理员级别的用户想要在此应用程序中给予其他用户更多控制权时,这将很有用。


    在这里进行数据访问控制的好方法是什么?

    4

    3 回答 3

    3
    1. 为您的实体添加一个安全密钥,为权限创建一个表,并将具有权限的用户与 entitytype 以及具有角色的安全密钥相关联。这样你就可以这样说:Admin_role 可以访问 Student(实体类型)并进行读取(Permission 中的操作)和 Write(操作),而 Student_role 可以为他/她自己访问 Student_key 和 Read_permission。您可以通过将地址重构为实体并向其添加安全密钥来修复地址。

      1. 您的第四个可能有一个封闭世界假设,并说除非您可以为用户的当前角色,否则将属性名称与字典中的标志(实体+属性)-哈希链接到标志,封闭世界假设因为默认情况下不允许读取。然后当然你没有得到任何写权限等。

      2. 您可以在数据库中定义视图并使用数据库身份验证系统为其分配权限。如果您能够自己编码,这可能是最干净的方式,根据我们的角色选择调用哪个视图的方式。(我以前的 RDBMS 老师会喜欢我这样说的 ;))这也与 Hibernate 有所不同,并将你的东西更多地耦合到数据库中。我猜这取决于您的代码需要多么可移动/可移植。

      3. 在您的通用 dao (IRepository) 周围使用一个方面,它根据您的权限重写查询;这意味着您当然在代码中具有基于权限的安全性。

    隐藏在 gui 中的编辑按钮实际上只有在您首先将权限移植到代码时才能完成,就像我的第 1 点一样。我建议您查看Ayendes 博客以了解其开源实现,他是一个非常熟练的人编码器。

    于 2009-02-18T04:38:26.593 回答
    2

    另一种选择可能是使用自定义类型。例如,不是将 char 映射到 String,而是将其映射到 SecureString 等自定义类型。在映射中给它一个带有某种唯一标识符的参数,例如 table.column。然后在自定义类型的 nullSafeGet 方法中,您可以调用安全服务来查看是填充值还是将其设置为 null。您可能还必须使用 ThreadLocal 来存储一些东西来识别用户或角色。您只需要创建一些自定义类型来包装字符串、双精度、日期、整数等。我已经做了类似的事情来允许将日期转换为用户的时区。

    于 2009-02-18T10:15:09.420 回答
    1

    我喜欢Henrik关于使用视图的建议。

    休眠过滤器可能会起作用,但我认为这些过滤器更多地用于过滤行而不是列。

    您还可以使用 [基于地图的动态模型](http://www.hibernate.org/hib_docs/reference/en/html/persistent-classes-dynamicmodels.html) 以及单独的 [命名查询](http:// www.hibernate.org/hib_docs/reference/en/html/querysql-namedqueries.html),而不是使用部分填充的 bean。然后您的视图代码将简单地检查地图是否包含“地址”条目,如果找到则显示该字段?
    于 2009-02-18T04:53:52.563 回答