身份验证令牌导致DBConcurrencyException

时间:2018-08-17 12:54:11

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

我正在使用.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);
    }

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

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

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

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

现在,我知道dbContext并不是以最佳方式进行管理的,但是鉴于这种情况,目前无法重构它。我可以为使用该API的网站发布新的访问令牌,但我认为该解决方案无法长期有效。

1 个答案:

答案 0 :(得分:0)

问题出在令牌生成上。我们为每个不会过期的环境发行了一些令牌(它们在大约一年后就到期了),因此我们在开发过程中不必担心这一点。但是,从一种环境发出的令牌确实可以在其他环境上使用,但这并不意味着该用户存在于数据库中。由于注释表基本上是目前我从UserId中提取Identity并将其保存到数据库的唯一地方,因此由于引用了不存在的外键而引发了异常。

外卖:

  • 请注意您如何发行访问令牌
  • 为更多描述性的例外祈祷