MultiTenant-Anwendung Verhindern des Zugriffs von Mandanten auf Daten anderer Mandanten in gemeinsam genutzten Datenbanken

Ich arbeite an einer Mieteranwendung und habe mich gefragt, wie ich den Mieterzugriff auf andere Mieterdaten blockieren kann.

assen Sie mich zunächst einige Fakten offenlegen:

Die App ist nicht kostenlos, 100% sicher, dass der böswillige Benutzer ein Client ist.Alle Primärschlüssel / Identitäten sind Ganzzahlen (Guid löst dieses Problem, aber wir können es momentan nicht ändern).Die App verwendet eine gemeinsame Datenbank und ein gemeinsames Schema.Alle Mieter sind Gewerbegruppen, die mehrere Geschäfte besitzen. Ich benutze Fälschung ...

Ich habe welcheremote data ausgewählt vonDropdown-List und es ist ganz einfach, die IDs und Zugriffsdaten anderer Mieter zu ändern. Wenn Sie ein wenig darüber wissen, können Sie die Daten anderer Mieter überprüfen.

Das erste, was ich denke, war überprüfen Sie jedes entfernte Feld, aber das ist irgendwie ärgerlich ...

So baue ich eine Lösung, die mit @ kompatibel iCode First Migrations usingModel Convention undComposite Keys, nur wenige getestet, arbeiten wie erwartet.

Hier ist die Lösung:

Convention Class

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 }
            }));
        });
    }
}

Convetion Anmeldung:

** Beim Konventionsregister übergebe ich zwei Eigenschaften, erstens den Primärschlüssel und zweitens die Mandanten-ID.

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

Base Entity Model

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

    public int CompanyId { get; set; }

    public Company Company { get; set; }
}

Order Entity (Beispiel)

** Hier beziehe ich die Währung und den Kunden mit der Firma und alle arbeiten wie erwartet ...

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; }
}
Gibt es irgendwelche Auswirkungen auf die Leistung? Gibt es einen Nachteil im Vergleich zur Prüfung jedes entfernten Feldes?Hat jemand die gleiche Idee und / oder das gleiche Problem und kam mit einer anderen Lösung?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage