如何避免“一个大应用程序用户”#34;模型?

时间:2014-04-23 18:58:00

标签: java security jdbc

我正在用Java编写一个小型Web应用程序,我的想法是将数据库用户用作应用程序用户。如果您从未听说过此问题,Oracle会在此document中推荐此方法。基本上,用户将使用他们的数据库凭据进行身份验证,我会将这些凭据转发到dbms以进行实际的身份验证过程。

我的问题是,每次我需要为用户打开连接时,我都需要他们的凭据。我想出了两个想法,但似乎对我来说似乎都不合适:

  1. 将jdbc连接对象存储在用户会话中,这样每次用户必须执行查询时我都不需要打开新的连接对象。这有其明显的缺点,here是关于这个主题的一个很好的讨论。
  2. 将用户凭据存储在会话中。这样我可以使用连接池,但在会话中存储密码是一种安全风险。无论哪种方式,这似乎比选项1更好,我可以加密密码,使整个事情变得更加不安全"。
  3. 还有其他我没想过的选择吗?如果没有,哪一个看起来最好?

2 个答案:

答案 0 :(得分:2)

我认为,在今天的应用程序中,您可以将应用程序用户映射到数据库用户的情况很少见。将此视为更多用户 - >角色映射。

这样说,在你的应用程序中,这是一种消息板,你将拥有一个包含表POSTS,USERS和SETTINGS的数据库。

然而,您将再次拥有三种用户类型:用户,版主和管理员。您可能会在所有这些用户之间进行某种控制器级别的分离,这意味着用户,版主和管理员可以使用一些单独的代码。该文章指出,您不应将一个超级用户数据库帐户用于所有目的。

考虑这个解决方案。对于Users组,您应该有一个USER数据库用户,该用户只对表POSTS具有WRITE权限。主持人的控制器应该使用一个单独的数据库用户连接到数据库,该用户有权通过POSTS读取和写入,但没有任何USERS和SETTINGS的许可。并且您可能怀疑管理员面板应该拥有自己的用户/角色,几乎具有所有权限。

当您要对留言板上的注册用户进行身份验证时,您可能还会放置另一个用户,只对USERS表具有读取权限。

这是一种相当简单的方法,但是这样您就可以防范数据库中的应用程序逻辑中可能存在的错误,这些错误可能会泄漏您不想破坏数据库的请求,或者至少可以控制可能的损坏。

总而言之,这是一个非常简单的机制(对于你正在构建的东西,我想这很简单)。这样你就不会真正得到任何供应商的锁定(如果你选择一天去MySQL或者SQLite或者那些与Oracle不同的东西的话)怎么办呢?你可以从你的控制器 - 模型解耦中获得更多。

正如一些评论员所指出的那样,有一天甚至可能会引入更复杂的身份验证方法,因此使用数据库集成机制会导致迁移问题。

答案 1 :(得分:0)

对数据库安全论文进行评分真是太好了!

一位大型应用用户的支持者"在开发人员,经理和管理员中有很多不好的公司,他们不想学习他们正在使用的DBMS。所有这些DBMS都具有丰富的审计和安全功能,如果您利用数据库级用户,这些功能非常宝贵。相反,OBAU将此抛弃了。

所以我会使用已命名的,已识别的数据库用户。但是,我宁愿用LDAP身份验证来保护每个这样的命名数据库用户而不是数据库。 (您可以使用Oracle LDAP服务器,但这不是重点。)我将LDAP会话凭据存储在Web会话中。请注意,我们希望凭据在过去几天或几小时后过期!

Oracle还实施了#34;轻量级"会话(11gR2?),你可以保持开放而不是汇集它们。我从来没有在连接池上完全出售 - 为什么数据库连接是管理员永远不会沿着摩尔定律生长的唯一资源"线?

您可以通过将同义词和视图收集到单个架构中来继续集中访问。您还可以将表存储在那里并使用VPD / DBMS_RLS进行保护,除了我的个人审美意识外,它总是以各种方式为我提供防弹。

连接后,让你的会话更改会话设置CURRENT_SCHEMA = CENTRALIZED_OWNER,这样你的程序员就不必为每个数据库对象添加CENTRALIZED_OWNER.tablename前缀。

尝试使用AUTHID CURRENT_USER(或其他DBMSes等价物)编写程序(在Oracle中),以便将权限管理保留在实际最终用户之下。

当您的开发人员尖叫访问表时,GRANT代理访问它们以获取该安装中的表所有者模式。这是一个很棒的功能。

祝你有美好的一天!

Andrew Wolfe