我正在开发旧版 Grails 应用程序。
我有几张这样的桌子:
User ( id, name,enterprise_id)
Enterprise (id, name)
Asset (id,description, enterprise_id)
我想验证当某个用户想要访问资产时,它具有正确的 enterprise_id (即该用户与资产属于同一企业)。
例如,考虑:
John,来自 Microsoft 的用户,以及 Charles(来自 Oracle),只有 Charles 应该能够访问 Java 虚拟机。
Enterprise
id,name
--------
1 Oracle
2 Microsoft
Asset
id,description,enterprise_id
----------------------------
1 Java VM 1
2 .NET 2
User
id name enterprise_id
----------------------
1 John 2
2 Charles 1
我一直在阅读Spring Security,但看起来它对我没有帮助。我看到的只是用户身份验证、密码、角色等(当然,我可能是错的)。这些东西已经安全并且工作正常。目前我正在考虑过滤器,但无法让它们工作并滚动我自己的安全性(参见这个问题),这似乎不对。
我应该做什么:Spring Security 是正确的选择吗?还是四郎?
您可以使用 spring-security-acl 来实现此功能(这取决于 spring-security-core)
否则,您可以使用一组对象级授权过滤器来实现两阶段方法(身份验证+授权)。
我为此使用 Hibernate Filter 插件。还有 MultiTenant 插件及其配套的 Falcone 插件。
这些所做的基本上是向所有数据库查询添加约束,以实现我认为您的目标。对您来说,一个典型的解决方案(使用 Hibernate Filter)是将其添加到资产域(更改每个新域的过滤器名称)...
static hibernateFilters = {
assetEnterpriseFilter(condition: ':enterpriseId=enterprise_id', types: 'integer', default: true)
}
...并从插件中提取 HibernateFilterFilters 以像这样覆盖(将会话变量设置为参数)...
class HibernateFilterFilters {
def filters = {
all(controller:'*', action:'*') {
before = {
def hibernateSession = grailsApplication.mainContext.sessionFactory.currentSession
DefaultHibernateFiltersHolder.defaultFilters.each {name ->
hibernateSession.enableFilter(name).setParameter('enterpriseId', session?.enterpriseId ? session.enterpriseId.toInteger() : new Integer(0))
}
}
after = {
}
afterView = {
}
}
}
}
...并确保不要在数据库中使用 enterprise_id = 0。
Apache Shiro 内置了访问控制,并且还有一个 grails 插件。
身份验证是证明某人身份真实的行为,即登录应用程序。授权是控制对某些数据或应用程序功能的访问的过程(控制“谁”可以做“什么”)。
Shiro 将这两个概念内置到其 API 中,并且做得很好 - 您甚至可以控制对单个实例的访问(例如,“查看”id 为 12345 的“用户”等)。我强烈建议您查看 Shiro 的 Grails 插件以及 Shiro 的发行版 - 它包括一些示例 Web 应用程序(带或不带 Spring),您可以了解如何使用其访问控制 - 可以使用基于 URL 的资源的 servlet 过滤器控制或通过注释来保护各个方法。