防止端点发生竞争

时间:2019-06-22 12:48:26

标签: c# asp.net-core race-condition

我正在为用户提供一个提取其余额的端点。

因此,在我的http服务中,我会执行以下操作:

var balance = currentBalance - withdrawlAmount;
ProcessWithdrawl(withdrawlAmount);
SaveBalance(balance);

这不是我的真实代码,只是一个用来说明自己的虚构示例。

我已经看到,当攻击者使用许多并行请求来触发不应该允许的操作时,许多流行的服务都会遇到这种麻烦,因为平衡已经耗尽。

防止这种情况的最简单方法是什么?一种想法是我使用静态对象并将代码包装在lock()语句中。但这一次只能让一个用户余额更新。

如何将锁定范围限定于用户身份验证会话?有没有简单的方法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

如评论中所述,由于您需要跨用户会话共享对象,因此我建议在服务器端使用shared / static data structure,它可以为每个用户提供唯一的对象。

  

案例1:单台服务器(没有网络花园)-不是群集或网络场

  1. 创建一个数据结构static ConcurrentDictionary<UserId,Object>,这里UserId是用户特定的唯一ID string, int, guid
  2. 根据用例使用Value对象进行锁定,它将创建用户特定的锁定/关键区域来进行操作
  3. lock(ConcurrentDictionary[UserId]) { ... }
  4. ConcurrentDictionary用于处理服务器端并发
  5. 锁定不是唯一的选择,您甚至可以计划用户特定的事件等待句柄,以信号通知特定用户等待并释放
  

案例2:集群或网络花园/农场

  1. 我们需要将对公共资源的访问转移到Cache, MQ, Database之类的分布式数据结构,该结构可以同步特定于用户的请求,并且所有用户都可以访问同一分布式资源
  2. 这里有多种选择,取决于系统设计和用例