9

マルチテナント ASP.NET MVC アプリをセットアップしたいと考えています。理想的には、このアプリには を含むルートがあり{tenant}/{controller}/{action}/{id}、それぞれtenantがアプリの論理インスタンス (単純に独立したマルチユーザー アカウント) を表します。

それがどのように行われるかの細かい詳細は、私にはまだはっきりしていません。ASP.NET MVC でこのようなマルチテナント スキームをセットアップするためのガイドはありますか?

4

2 に答える 2

12

私は現在、ASP.Net MVC、フォーム認証、およびメンバーシップ/ロール/プロファイル用の SQL プロバイダーを使用して、同様のプロジェクトに取り組んでいます。これが私が取っているアプローチです:

  1. デフォルトルートを `{tenant}/{controller}/{action}/{id} として登録

  2. 標準 MVC テンプレートに付属する FormsAuthenticationService のデフォルトの動作を変更します。認証チケットの UserData に (ルートからの) テナント名を含めるように設定する必要があります。

    public void SignIn(string userName, bool createPersistentCookie, string tenantName)
    {
        var ticket = new FormsAuthenticationTicket(1, userName, DateTime.Now, DateTime.Now.AddMinutes(30),
                                                   createPersistentCookie, tenantName);
        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket));
        HttpContext.Current.Response.AppendCookie(cookie);
    }
    
  3. global.asax ファイルで、テナントのセキュリティ チェックを行い、1 つのメンバーシップ データベース内のテナント間でユーザーを分割できるようにします。

    protected void Application_AuthenticateRequest(object sender, EventArgs e)
    {
        //Since this method is called on every request
        //we want to fail as early as possible
        if (!Request.IsAuthenticated) return;
        var route = RouteTable.Routes.GetRouteData(new HttpContextWrapper(Context));
        if (route == null || route.Route.GetType().Name == "IgnoreRouteInternal") return;
        if (!(Context.User.Identity is FormsIdentity)) return;
        //Get the current tenant specified in URL 
        var currentTenant = route.GetRequiredString("tenant");
        //Get the tenant that that the user is logged into
        //from the Forms Authentication Ticket
        var id = (FormsIdentity)Context.User.Identity;
        var userTenant = id.Ticket.UserData;
        if (userTenant.Trim().ToLower() != currentTenant.Trim().ToLower())
        {
            //The user is attempting to access a different tenant
            //than the one they logged into so sign them out
            //an and redirect to the home page of the new tenant
            //where they can sign back in (if they are authorized!)
            FormsAuthentication.SignOut();
            Response.Redirect("/" + currentTenant);
            return;
        }
        //Set the application of the Sql Providers 
        //to the current tenant to support partitioning
        //of users between tenants.
        Membership.ApplicationName = currentTenant;
        Roles.ApplicationName = currentTenant;
        ProfileManager.ApplicationName = currentTenant;
    }
    
  4. 各テナントのデータを分割します。次の 2 つのオプションがあります。

    4a. テナントごとに個別のデータベースを使用します。これにより、テナントに最適なデータ セキュリティが提供されます。共有メンバーシップ データベースで、各テナントの一意の appid をキーとするテーブルを追加し、このテーブルを使用して、現在のテナントに基づいて接続文字列を格納および取得します。

    4b. すべてのデータを 1 つのデータベースに格納し、各テーブルを一意のテナント ID でキー設定します。これにより、テナントのデータ セキュリティがわずかに低下しますが、使用する SQL Server ライセンスは 1 つだけです。

于 2010-03-09T18:39:17.253 に答える
2

これらのリンクが役に立つと思われます

于 2009-11-09T09:28:24.477 に答える