Приложение MultiTenant предотвращает доступ арендатора к данным других арендаторов в общей базе данных

Я работаю над приложением арендатора, и мне было интересно, как я могу заблокировать доступ арендатора к другим данным арендатора.

Во-первых, позвольте мне изложить некоторые факты:

Приложение не бесплатное, на 100% точно злоумышленник является клиентом.Все первичные ключи / идентификаторы являются целыми числами (Guid решает эту проблему, но мы не можем сейчас изменить).Приложение использует общую базу данных и общую схему.Все арендаторы - бизнес-группа, владеющая несколькими магазинами.Я использую подделку ...

у меня есть немногоудаленные данные выбранопадать и легко изменять идентификаторы и данные доступа от других арендаторов, если у вас мало знаний, вы можете получить данные других арендаторов.

Первое, что я думаю, это проверить каждое удаленное поле, но это немного раздражает ...

Поэтому я создаю решение, совместимое сКод Первые Миграции с помощьюТиповая конвенция а такжеКомпозитные ключиМало кто тестировал, работает как положено.

Вот решение:

Конвенционный класс

public class TenantSharedDatabaseSharedSchemaConvention<T> : Convention where T : class
{
    public Expression<Func<T, object>> PrimaryKey { get; private set; }

    public Expression<Func<T, object>> TenantKey { get; private set; }

    public TenantSharedDatabaseSharedSchemaConvention(Expression<Func<T, object>> primaryKey, Expression<Func<T, object>> tenantKey)
    {
        this.PrimaryKey = primaryKey;
        this.TenantKey = tenantKey;

        base.Types<T>().Configure(m =>
        {
            var indexName = string.Format("IX_{0}_{1}", "Id", "CompanyId");

            m.Property(this.PrimaryKey).IsKey().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnOrder(0).HasColumnAnnotation("Index", new IndexAnnotation(new[] {
                new IndexAttribute(indexName, 0) { IsUnique = true }
            }));

            m.Property(this.TenantKey).IsKey().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None).HasColumnOrder(1).HasColumnAnnotation("Index", new IndexAnnotation(new[] {
                new IndexAttribute(indexName, 1) { IsUnique = true }
            }));
        });
    }
}

Конвекционная регистрация:

** В регистре соглашений я передаю два свойства: первый - первичный ключ, а второй - идентификатор арендатора.

modelBuilder.Conventions.Add(new TenantSharedDatabaseSharedSchemaConvention<BaseEntity>(m => m.Id, m => m.CompanyId));

Модель базовой сущности

public class BaseEntity
{
    public int Id { get; set; }

    public int CompanyId { get; set; }

    public Company Company { get; set; }
}

Заказать объект (пример)

** Здесь я указываю валюту и клиента с компанией, и все работает как ожидалось ...

public class Order : BaseEntity
{
    [Required]
    public int CurrencyId { get; set; }

    [ForeignKey("CompanyId, CurrencyId")]
    public virtual Currency Currency { get; set; }

    [Required]
    public int ClientId { get; set; }

    [ForeignKey("CompanyId, ClientId")]
    public virtual Client Client { get; set; }

    public string Description { get; set; }
}
Есть ли влияние на производительность?Есть ли недостаток по сравнению с проверкой каждого удаленного поля?У кого-то есть такая же идея и / или проблема, и они пришли с другим решением?

Ответы на вопрос(1)

Ваш ответ на вопрос