【问题标题】:MultiTenant Application Prevent Tenant Access Data from Other Tenant in Shared Database多租户应用程序阻止租户访问共享数据库中其他租户的数据
【发布时间】:2015-06-10 01:34:46
【问题描述】:

我正在开发一个租户应用程序,我想知道如何阻止租户访问其他租户数据。

首先,让我揭露一些事实:

  1. 该应用不是免费的,100% 可以肯定恶意用户是客户端。
  2. 所有主键/标识都是整数(Guid 解决了这个问题,但我们现在无法更改)。
  3. 该应用使用共享数据库和共享架构。
  4. 所有租户均为商业集团,拥有数间店铺。
  5. 我正在使用 Forgery...

我有一些 下拉列表 选择的远程数据,它可以轻松更改其他租户的 id 和访问数据,如果您有一点了解,您可以了解其他租户数据。

我认为第一件事是检查每个远程字段,但这有点烦人......

因此,我使用 Model ConventionComposite Keys 构建了一个与 Code First Migrations 兼容的解决方案,很少经过测试,可以按预期工作。 p>

解决办法如下:

约定类

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

大会注册:

** 在约定注册时,我传递了两个属性,第一个是主键,第二个是租户 ID。

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. 对性能有影响吗?
  2. 与检查每个远程字段相比有什么缺点吗?
  3. 有人有相同的想法和/或问题并提出了另一种解决方案?

【问题讨论】:

  • 为什么我的帖子被否决

标签: asp.net-mvc entity-framework ef-code-first entity-framework-migrations multi-tenant


【解决方案1】:

恕我直言,在应用程序的任何地方,您都将拥有一个映射,表明用户 x 有权管理或访问租户 a(,b)。在您的业务层中,您应该检查用户是否有权使用伪造的 ID 查看数据。在您的情况下,伪造的 Id 将属于用户无权访问的另一个租户,因此您将返回未经授权/违反安全的异常。

HTH

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 2014-03-21
    • 2019-05-18
    • 2014-11-01
    • 2012-12-14
    • 2020-06-17
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    相关资源
    最近更新 更多