从共享数据库的其他租户多租户应用prevent租户访问数据 [英] MultiTenant Application Prevent Tenant Access Data from Other Tenant in Shared Database

查看:246
本文介绍了从共享数据库的其他租户多租户应用prevent租户访问数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个租户应用程序,我想知道我怎么可以阻止租户访问其他租户的数据。

首先,请允许我揭露一些事实:


  1. 应用程序是不是免费的,100%确保恶意用户是一个客户端。

  2. 所有的主键/身份是整数(GUID解决这个问题,但现在我们不能改变)。

  3. 该应用程序使用共享数据库和共享模式。

  4. 所有租户的商业集团至极的几家商店。

  5. 我使用伪造...

我有一些的远程数据下拉菜单并其易于变化的id和接取数据来自其他租户,选择,如果你有一点点知识,你可以他妈的其他租户的数据。

我想的第一件事就是检查每个远程现场但这是一种恼人的...

所以我建立与 code首先迁移兼容的解决方案使用的示范公约组合键,几个测试,工作正常


  

下面是解决方案:


公约类

 公共类TenantSharedDatabaseSharedSchemaConvention< T> :公约其中T:类
{
    公共防爆pression<&Func键LT; T,对象>> PrimaryKey的{搞定;私人集; }    公共防爆pression<&Func键LT; T,对象>> TenantKey {搞定;私人集; }    公共TenantSharedDatabaseSharedSchemaConvention(前pression<&Func键LT; T,对象>>的Pri​​maryKey,防爆pression<&Func键LT; T,对象>> tenantKey)
    {
        this.PrimaryKey = PrimaryKey的;
        this.TenantKey = tenantKey;        base.Types< T>()配置(M =>
        {
            变种INDEXNAME =的String.Format(IX_ {0} _ {1},标识,CompanyId);            m.Property(this.PrimaryKey).IsKey().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).HasColumnOrder(0).HasColumnAnnotation(\"Index\",新IndexAnnotation(新[] {
                新IndexAttribute(INDEXNAME,0){= isUnique设置真实}
            }));            m.Property(this.TenantKey).IsKey().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None).HasColumnOrder(1).HasColumnAnnotation(\"Index\",新IndexAnnotation(新[] {
                新IndexAttribute(INDEXNAME,1){= isUnique设置真实}
            }));
        });
    }
}

Convetion注册:

**在约定注册我通过两个属性,首先是主键,第二个是租户ID。

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

基本实体模型

 公共类BaseEntity
{
    公众诠释标识{搞定;组; }    公众诠释CompanyId {搞定;组; }    公众公司的公司{搞定;组; }
}

Order实体(例)

**在这里,我引用预期的货币和客户与公司及全体工作...

 公共类订单:BaseEntity
{
    [需要]
    公众诠释CurrencyId {搞定;组; }    [ForeignKey的(CompanyId,CurrencyId)]
    公共虚拟货币货币{搞定;组; }    [需要]
    公众诠释客户端Id {获取;组; }    [ForeignKey的(CompanyId,客户端Id)]
    公共虚拟客户端{搞定;组; }    公共字符串描述{搞定;组; }
}


  1. 有没有效果?任何影响

  2. 有没有比较,以检查每个远程领域的任何缺点?

  3. 有人有同样的想法和/或问题,并与其他解决方案来的?


解决方案

恕我直言,在应用程序中的任何地方,你将有指出用户X有权管理或映射访问租客(S)A(,B) 。在你的业务层,你应该检查该用户曾经有权查看使用伪造的ID数据。你的情况,伪造我将属于另一个租户,用户不能访问,所以你会返回一个未授权/安全违反异常。

心连心

I’m working on a tenant application and i was wondering how i can block tenant access other tenant data.

First, let me expose some facts:

  1. The app is not free, 100% for sure the malicious user is a client.
  2. All the primary keys/identity are integers (Guid solve this problem but we can't change right now).
  3. The app use shared database and shared schema.
  4. All the tenants are business group wich own several shops.
  5. I'm use Forgery...

I have some remote data chosen by dropdown and its easy change the id's and acess data from other tenants, if you have a little knowledge you can f*ck other tenants data.

The first thing i think was check every remote field but this is kind annoying...

So i build a solution compatible with Code First Migrations using Model Convention and Composite Keys, few tested, working as expected.

Here's the solution:

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 Registration:

** On convention register i pass two properties, first the primary key and second is the tenant 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 (Example)

** Here i reference the currency and client with company and all work as expected...

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. Is there any impact on performance?
  2. Is there any disadvantage compared to check every remote field?
  3. Someone have the same idea and/or problem and came with another solution?

解决方案

IMHO, anywhere in the application, you will be having a mapping that states that user x is entitled to manage or access tenant(s) a(,b). In your businesses layer you should check it the user is ever entitled to see the data using the forged ID. In your case, the forged I'd will belong to another tenant that the user does not have access to, so you will return an unauthorized / security violation exception.

HTH

这篇关于从共享数据库的其他租户多租户应用prevent租户访问数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆