最近我一直在做一个简单的状态跟踪系统,它的主要目的是持久化更新,定期从移动的客户端发送到关系数据库中,以便进一步分析/呈现。
移动的客户端使用AAD发布的JWT来验证我们的API。我需要找到一种方法来验证用户是否有权发送某个项目的更新(目前只有其创建者可以这样做)。
我们假设这些更新可以由许多客户端以很小的间隔(15-30秒)发送。我们将只有一个项目处于活动状态的每个用户。
后端应用程序基于Spring-Boot,使用带有MS AAD启动器和Spring Data JPA的Spring Security。
显然,我们只需执行以下操作:
1.用户_1创建项目_1
- User_1发送Item_1的更新
Item有一个owner_ID字段,在插入Update之前,我们只需检查Item_1.owner_ID是否=User_1.ID -这意味着我们需要在每次插入之前获取原始Item。
我想知道是否有更优雅的方法来解决这类问题。我们是否应该使用某种缓存解决方案来保存允许的ID对,例如{User_1,Item_1}?
1条答案
按热度按时间zvokhttg1#
WHERE
子句您可以将它作为条件包含在WHERE子句中。例如,如果您正在更新记录X,则可能以下列内容开头:
但是,您可以改为:
如果所有者不是Y,那么这个值就不会被更新。
其中,
principal
是从Authentication#getPrincipal
返回的值。缓存
从技术上讲,缓存可以阻止第一次数据库调用,这是正确的,但它会引入其他复杂性。保持缓存新鲜就足够了,只有当引入缓存的复杂性显然会带来所需的、观察到的性能增益时,我才会尝试它。
@PostAuthorize
或者,您可以进行额外的调用,并使用框架来简化样板文件。例如,您可以在控制器中使用
@PostAuthorize
注解,如下所示:通过这种安排,Spring Security将根据登录的用户检查返回值的ownerId,如果失败,则事务将被回滚,并且更改不会进入数据库。
要使其正常工作,请确保Spring的事务拦截器位于Spring Security的授权后拦截器之前,如下所示:
这个解决方案的缺点是仍然有两个相同的DB调用。我喜欢它,因为它允许框架强制执行授权规则。要了解更多信息,请看一下遵循此模式的this sample application。