休眠/春季:有行级安全性吗?

斯蒂芬·福克

我不确定Spring Security的功能是否正确。

我的问题是,我想防止已登录的用户向服务器发送任意ID,从而访问不属于他的数据但是我能找到的每个教程都是关于一个简单的登录过程的但是我怎么用它来摆脱

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 Security甚至有可能吗?

可能起作用的另一件事休眠过滤器,但是我不确定我是否希望我的数据库知道我的数据的安全性方面。

因此,我对如何正确执行此操作感到困惑。有任何想法吗?

埃里克·R·拉斯

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

  • 创建Springorg.springframework.security.acls.model.AclService接口的实现,该实现知道如何返回给定主体对给定域对象的权限。例如,如果委托人与此域对象的关系为foo,则授予READ和WRITE权限;如果是关系栏,则授予READ,WRITE和DELETE权限。
  • 向在域对象上运行的服务方法添加诸如的注释,org.springframework.security.access.prepost.PreAuthorizeorg.springframework.security.access.prepost.PreAuthorize定义要实施的访问控制断言。例如,此方法要求当前经过身份验证的用户对类型X的参数具有“写”权限,或者该方法要求当前经过身份验证的用户对返回对象具有“ READ”权限。如果任何一个断言失败,AccessDeniedException将抛出一个。
  • 调整您的Spring Social配置以打开方法级安全性。global-method-security在Spring Security的XML名称空间中使用了元素。

有很多细节需要考虑,但是我们在一些Web应用程序中使用这种方法效果很好。它使您可以将“对象获得哪些权限”逻辑与执行该操作所需的“权限”逻辑分开,并且使这两个逻辑都不受数据库查询的影响。

当然,在某些情况下,您将希望在查询中强制执行访问控制,而不是先查询然后过滤结果。我已经看到过“早期绑定”一词用于描述数据库查询中访问控制的执行,而“后期绑定”一词则用于描述对查询结果的访问控制。Spring Security 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>

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章