2012-04-17 8 views
1

MultiTenancyの処理方法に関するご意見をお聞きしたいと思います。 I "私のバックエンドとしてMVC3(MVC4への切り替え)とEFを使用して、私は、単一のアプリケーション、共有スキーママルチテナントを使用しています以下は、mはコードです:。。もちろんDIのMVCでのMulti Tenancyの処理

public abstract class Service<T> where T : Entity 
{ 
    private Repository<T> _repo; 
    public Service() 
    { 
     _repo = new Repository<T>(); 
    } 

    public bool Authenticate(int id) 
    { 
     //var companyInfo = _authorizationRepository.GetApiKey(apiKey); 
     int tenantId = 0; // replaced by companyInfo using repository 
     var entity = _repo.GetQuery(tenantId).Where(e => e.Id == id).First(); 

     if (tenantId != entity.TenantId) 
      throw new ArgumentException(); 

     return true; 
    } 
} 

public class EmployeeService : Service<Employee> 
{ 
    private EmployeeRepository employeeRepository; 
    public EmployeeService() 
    { 
     employeeRepository = new EmployeeRepository(); 
    } 

    public Employee GetEmployeeById(int employeeId) 
    { 
     this.Authenticate(employeeId); 
     return employeeRepository.GetById(employeeId); 
    } 
} 

public class Entity 
{ 
    public int Id { get; set; } 
    public int TenantId { get; set; } 
} 

が同様に存在しますが、用シンプルさ私はここでそれらを削除しました(一時的に)。私はジェネリックス(それについて汚れている)をサービスレイヤーで使用しました。テナントIDとクラスに渡される正しいエンティティとの比較に問題があります。これはFilterAttributesを使用していますが、どのようにすればいいのかわかりません。あなたのマルチテナント性はどうやって処理しますか?設計には長期的に遭遇する可能性のある重大な欠陥がありますか?

Th anks!

+0

なぜWebアプリケーションでマルチテナントが問題になるのですか? – Tejs

+0

@Tejs私の懸念は、ルーティングをどのように処理するかということです。基本的にtenant1.domain.comとdomain.com/tenant2の両方が有効で、特定のテナントを指している必要があります。 – MikeSW

+0

それは素晴らしいですが、その特定のURLスキームは、使用することを決めた永続性レイヤーとは関係ありません。私はあなたの質問が何であるか疑問に思います。 – Tejs

答えて

2

現時点ではかなり大きなマルチテナントウェブアプリを構築しています。それはそう簡単ではありませんが、一度あなたのアーキテクチャを構築すれば、それはまっすぐです。私たちは深く開発していますが、nanocms.codeplex.comのオープンソースの部分をチェックすることができます(数日でdb jetのバットをアップロードしていません)

これはかなり広い質問です。いくつかの問題と解決方法を要約してみてください。

まず、リクエストごとにテナントを特定する必要があります。 urlを解析し、データベースのデータと比較するグローバルアクションフィルタがあります。もちろん、データベースへの呼び出しが行われないように、すべてのデータをキャッシュする必要があります。一度に複数のテナントを訪問することができるので、クッキーまたはセッションにそれらを保存してはいけません。そのデータをHttpRequest Itemsに入れることをお勧めします。そのため、リクエストでは1回だけ行いますが、そのデータは常に利用可能です。

認証ユーザーは一意である必要があります。テナントごとに異なる権限をユーザに付与したいと考える必要があります。そうであれば、現在のテナントで彼の役割を確認できるように、認証コードと属性を記述する必要があります。私たちのアプリでは、ユーザー認証時にセッションオブジェクトを作成します。オブジェクトには、テナントの権利をチェックする静的メソッドがあります。

HttpRequest Itemsを強く入力することをお勧めします。我々は持っています:

public static int TenantID { 
    get { return System.Web.HttpContext.Current.Items.Contains("TenantID") ? Convert.ToInt32(System.Web.HttpContext.Current.Items["TenantID"]) : -1; } 
    set { 
     if (!System.Web.HttpContext.Current.Items.Contains("TenantID")) 
      System.Web.HttpContext.Current.Items.Add("TenantID", value); 
     System.Web.HttpContext.Current.Items["TenantID"] = value; 
    } 
} 
+0

Goranにお返事ありがとうございます。しかし、投稿されるエンティティが間違ったテナントに行くことはないかどうかをどうやって確認しますか?例えば、TenantAはアイテムを挿入/選択します。TenantAがTenantBのデータを選択/挿入しないようにするにはどうしたらいいですか? – gnaungayan

+0

クロス・ポスティングのセキュリティに関心があるのか​​、正しいコンテンツを正しいテナントに提供するだけでいいのか説明してください。セキュリティのために、クロスポストを防ぐ偽造トークンを使用することができます。正しいコンテンツを確保するためには、データベース内のすべての親テーブルにtenantIdを設定し、それに応じてクエリを記述する必要があります。 –

+0

あなたの2番目の声明にもっと似ています。 www.site.com/Employees/1のURL(これはTenantAデータに属しますが)がTenantBにログオンしており、そのURLをハードコードしている場合、TenantAデータを表示できないようにするにはどうすればよいですか? – gnaungayan

関連する問題