У меня есть контекст базы данных, который я хотел бы отфильтровать, чтобы вошедший в систему пользователь мог видеть только те элементы, которыми он владеет.Я хочу указать этот фильтр только в контексте базы данных, поэтому мне не нужно пытаться поддерживать его в нескольких местах.Конечным результатом является добавление фильтра в контекст моей базы данных:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Foo>().HasQueryFilter(f => f.OwnerId == getCurrentUserIdSomehow())
}
Что я пробовал:
Я думал создатьсервис, который получает текущего пользователя, выполнившего вход в систему следующим образом:
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();
}
}
}
Затем я могу внедрить его во время метода ConfigureServices()
в Startup
:
services.AddTransient<IUserProvider, UserIdProvider>();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Затем один разЯ вставил этот сервис в конструктор контекста моей базы данных, мой фильтр становится:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<Foo>().HasQueryFilter(f => f.OwnerId == _userProvider.GetUserId())
}
Это работает, но есть ли более простой или чистый способ сделать это?Такое ощущение, что при создании контекста базы данных должен быть более простой способ найти текущий идентификатор пользователя.
Я думал о внедрении службы UserManager
в контекст моей базы данных, но не смог найти способ получитьтекущий пользователь.