マルチテナント ASP.NET MVC アプリをセットアップしたいと考えています。理想的には、このアプリには を含むルートがあり{tenant}/{controller}/{action}/{id}
、それぞれtenant
がアプリの論理インスタンス (単純に独立したマルチユーザー アカウント) を表します。
それがどのように行われるかの細かい詳細は、私にはまだはっきりしていません。ASP.NET MVC でこのようなマルチテナント スキームをセットアップするためのガイドはありますか?
マルチテナント ASP.NET MVC アプリをセットアップしたいと考えています。理想的には、このアプリには を含むルートがあり{tenant}/{controller}/{action}/{id}
、それぞれtenant
がアプリの論理インスタンス (単純に独立したマルチユーザー アカウント) を表します。
それがどのように行われるかの細かい詳細は、私にはまだはっきりしていません。ASP.NET MVC でこのようなマルチテナント スキームをセットアップするためのガイドはありますか?
私は現在、ASP.Net MVC、フォーム認証、およびメンバーシップ/ロール/プロファイル用の SQL プロバイダーを使用して、同様のプロジェクトに取り組んでいます。これが私が取っているアプローチです:
デフォルトルートを `{tenant}/{controller}/{action}/{id} として登録
標準 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);
}
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;
}
各テナントのデータを分割します。次の 2 つのオプションがあります。
4a. テナントごとに個別のデータベースを使用します。これにより、テナントに最適なデータ セキュリティが提供されます。共有メンバーシップ データベースで、各テナントの一意の appid をキーとするテーブルを追加し、このテーブルを使用して、現在のテナントに基づいて接続文字列を格納および取得します。
4b. すべてのデータを 1 つのデータベースに格納し、各テーブルを一意のテナント ID でキー設定します。これにより、テナントのデータ セキュリティがわずかに低下しますが、使用する SQL Server ライセンスは 1 つだけです。