【问题标题】:Authentication token causes DBConcurrencyException身份验证令牌导致 DBConcurrencyException
【发布时间】:2018-08-17 21:25:12
【问题描述】:

我正在使用 .Net 框架和实体框架构建 REST Web API。我们正在使用 OAuth 2.0 授权,所有请求都必须具有有效的访问令牌才能使用 API。

我的服务出现了相当意外的行为。业务服务正在做这样的事情:

Create the entity add it to the db generate the system comment that entity was created add the comment to the

public void Task<MyEntity> Create(entity){

        _entityRepository.Add(entity);

        await _dbContext.SaveChangesAsync().ConfigureAwait(false);

        await _entityCommentBusinessService.AddSystemComment(entity, EntitySystemCommentTypes.StatusChangedNewEntity).ConfigureAwait(false);
        await _bookingArtifactService.SetValidity(entity.Id).ConfigureAwait(false);

        return entity;

添加系统评论生成评论模型并调用AddComment:

    public async Task<CommentModel> AddComment(CommentModel model)
    {
        var entity = repository.Create();
        repository.Add(entity);

        MapModelToEntity(model, entity);

        entity.UserId = identity.UserId;
        await context.SaveChangesAsync().ConfigureAwait(false);

        return MapEntityToModel(entity);
    }

当执行点到达AddComment 方法内部的SaveChangesAsync() 时,将引发异常。

当我使用一个访问令牌实例(为了清楚起见,它没有过期)时,我得到Data exception。 但是,如果我使用不同的令牌(再次明确没有过期)并且操作成功完成,则不会发生此问题。

另外,如果我确实使用了未经授权的访问令牌,我会得到未经授权的 401,这是预期的行为。

我尝试将这些操作包装到 TransactionScope 中,但问题仍然存在。 由于评论必须通过 ID 引用实体,因此无法绕过两次保存更改。

现在我知道 dbContext 没有以最好的方式进行管理,但考虑到目前重构它的成本太高。我可以为使用此 API 的网站颁发新的访问令牌,但我认为该解决方案不会长期有效。

【问题讨论】:

    标签: c# .net rest asp.net-web-api oauth


    【解决方案1】:

    问题在于令牌生成。我们为每个环境发布了几个不会过期的令牌(它们会在大约一年内过期),因此我们不必在开发过程中担心这一点。但是,从一个环境发出的令牌确实适用于其他环境,但这并不意味着用户存在于数据库中。由于 cmets 表基本上是目前我从 Identity 中提取 UserId 并将其保存到数据库的唯一位置,因此引发了异常,因为引用了不存在的外键。

    要点:

    • 请注意颁发访问令牌的方式
    • 祈求更多描述性的例外情况

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 2019-11-24
      • 1970-01-01
      相关资源
      最近更新 更多