当前用户 ID 进入数据库上下文的全局过滤器

Kyl*_*ard 8 c# entity-framework-core asp.net-core asp.net-core-2.0

我有一个数据库上下文,我想过滤它,以便登录的用户只能看到他们拥有的项目。我只想在数据库上下文中指定此过滤器,因此我不必尝试在多个位置维护它。最终结果是将这样的过滤器添加到我的数据库上下文中:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.Entity<Foo>().HasQueryFilter(f => f.OwnerId == getCurrentUserIdSomehow())
}
Run Code Online (Sandbox Code Playgroud)

我尝试过的:

我的想法是创建一个服务来获取当前登录的用户,如下所示:

public interface IUserProvider
{
    string GetUserId();
}

public class UserIdProvider : IUserProvider
{
    private IHttpContextAccessor _accessor;
    public UserIdProvider(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }

    public string GetUserId()
    {
        var identity = _accessor.HttpContext.User.Identity;
        if (identity.IsAuthenticated)
        {
            return _accessor.HttpContext.User
                .FindFirst(ClaimTypes.NameIdentifier).Value.ToString();
        }
        else
        {
            return Guid.Empty.ToString();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ConfigureServices()然后,我可以在以下方法中注入它Startup

services.AddTransient<IUserProvider, UserIdProvider>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)

然后,一旦我将该服务注入到数据库上下文的构造函数中,我的过滤器就会变成:

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    builder.Entity<Foo>().HasQueryFilter(f => f.OwnerId == _userProvider.GetUserId())
}
Run Code Online (Sandbox Code Playgroud)

这可行,但是有没有更简单或更干净的方法来做到这一点?感觉在构建数据库上下文时应该有一种更简单的方法来查找当前用户 ID。

我考虑过将UserManager服务注入到我的数据库上下文中,但找不到获取当前用户的方法。