Hibernate/Spring:有行级安全吗?

Hibernate/Spring: Is There Row-Level Security?

我不确定我是否正确理解了 Spring 安全功能。

我的问题是,我想要prevent a logged in user to send arbitrary IDs to my server and therefore access data that does not belong to him. But every tutorial I can find is about a simple login procedure。但是我怎样才能用它来摆脱

if(item .getStore().getId() == store.getId()) { /* .. */ }

在这个例子中:

// StoreService.java

@Transactional
public ItemDTO deleteItem(String sessionId, Long storeId, ItemDTO itemDto) {

    // sessionId is the cookie I have placed in my database
    // This way I want to ensure that I am only accessing a store
    // that is associated with the logged in store owner (the user basically)
    Store store = this.storeOwnerRepository.getStore(sessionId, storeId);

    Item item = ConvertDTO.convertItem(store, itemDto);

    // THIS CHECK IS WHAT I WANT TO GET RID OF:
    // Check if the store ID that I got using the cookie is the
    // same ID as the store ID from the item that should be deleted
    if(item.getStore().getId() == store.getId()) {
        item = this.storeOwnerRepository.deleteItem(item);
    } else {
        // If this didn't work we have a potentially hostile user:
        throw new RuntimeException("Is somebody trying to delete items from a store he doesn't own?");
    }

    itemDto = ConvertEntity.convertItem(item);
    return itemDto;
}

使用 Spring 注释? Spring 安全性甚至可能吗?

另一件 可能 起作用的事情是 Hibernate Filters 但我不确定我是否希望我的数据库了解我的数据的安全方面。

所以我很困惑如何正确地做到这一点。有什么想法吗?

可能您应该实施 Spring 安全和工作角色和权限,这样您将能够确保您不会收到非管理员用户的请求(通过使用 [=10= 分隔方法) ] ,这可以帮助你,以防你将来担任其他角色。

那么你应该更多地使用角色权限

Spring Security with roles and permissions

然后添加对商店的权限,以读取或写入它们。您可以将许多权限关联到一个用户,因此,可以 read/write/whatever 只关联您想要的商店。

查看本教程,它可以帮助你。

http://slackspace.de/articles/roles-permissions-with-spring-security-3/

http://springinpractice.com/2010/10/27/quick-tip-spring-security-role-based-authorization-and-permissions

我认为你所说的与验证有关,而不是与安全有关。

只要您将多个 clients/customers 的数据存储在同一个数据库中,就必须注意防止用户无意(或恶意)访问彼此的数据。

我建议您在 Web 服务层执行此验证,并将业务逻辑集中在需要完成的事情的细节上。

我们已经使用 Spring's ACL API 在域对象上实现了这种安全性。这涉及:

  • 创建 Spring 的 org.springframework.security.acls.model.AclService 接口的实现,该接口知道如何 return 给定主体对给定域对象的权限。例如。如果委托人与该域对象有 foo 关系,则授予 READ 和 WRITE 权限;如果是关系栏,则授予读取、写入和删除权限。
  • 向服务方法添加对域对象注释的操作,例如 org.springframework.security.access.prepost.PreAuthorizeorg.springframework.security.access.prepost.PreAuthorize,它们定义了要强制执行的访问控制断言。例如。此方法要求当前经过身份验证的用户对类型 X 的参数具有 "WRITE" 权限,或者该方法要求当前经过身份验证的用户对 return 对象具有 "READ" 权限。如果任一断言失败,将抛出 AccessDeniedException
  • 正在调整您的 Spring 社交配置以打开方法级安全性。我在 Spring 安全的 XML 命名空间中使用了 global-method-security 元素。

需要考虑的细节很多,但我们在几个web应用中使用了这种方法,效果很好。它允许您将谁在哪些对象上获得什么权限的逻辑与执行此操作需要什么权限的逻辑分开,并且它使两者远离您的数据库查询。

当然,在某些情况下,您会希望在查询中强制执行访问控制,而不是先进行查询,然后过滤结果。我见过术语 "early binding" 用于描述数据库查询中访问控制的实施,而 "late binding" 用于描述对查询结果的访问控制。 Spring 安全 ACL API 是一个非常好的、强大的后期绑定解决方案。

您最终会得到如下业务服务方法:

@PostAuthorize("hasPermission(returnObject, 'READ')")
public MyItem getMyItem(Long id) {
    return dao.getMyItem(id);
}

@PreAuthorize("hasPermission(#toDelete, 'DELETE')")
public void deleteMyItem(MyItem toDelete) {
    dao.delete(toDelete);
}

还有一个 AclService,其方法如下:

public Acl readAclById(ObjectIdentity objectIdentity, List<Sid> sids) throws NotFoundException {
    /*
examines objectIdentity which identifies domain object in question, and sids which identifies the principal who wants permissions on the domain object, then returns an ACL instance with permission grants on that domain object for that/those principals
    */
    return new AclImpl(...);
}

以及您的 applicationContext-security.xml 中的以下内容:

<beans:bean id="permissionEvaluator"
    class="org.springframework.security.acls.AclPermissionEvaluator">
    <beans:constructor-arg ref="aclServiceImpl" />
</beans:bean>
<beans:bean id="expressionHandler"
    class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <beans:property name="permissionEvaluator" ref="permissionEvaluator" />
</beans:bean>
<global-method-security pre-post-annotations="enabled">
    <expression-handler ref="expressionHandler" />
</global-method-security>