asp.net-mvc – 使用ASP.NET MVC设置路由{tenant} / {controller} / {action} / {id}?

我想设置一个多租户ASP.NET MVC应用程序.理想情况下,此应用程序将具有{tenant} / {controller} / {action} / {id}的路由,每个租户代表应用程序的逻辑实例(只是独立的多用户帐户)

细粒度的细节对我来说还是很不清楚.任何可用于使用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文件中进行一些租户安全检查,并允许在一个成员资格数据库中的租户之间分配用户

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

>对每个租户数据进行分区.这有两个选择:

4A.为每个租户使用单独的数据库.这为您的租户提供了最佳的数据安全性.在共享成员资格数据库中,添加一个表,该表在每个租户的唯一appid上键入,并使用此表存储和检索基于当前租户的连接字符串.

4B.将所有数据存储在一个数据库中,并将每个表键入唯一的租户ID.这为您的租户提供的数据安全性略低,但仅使用一个SQL Server许可证.

相关文章

引言 本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个...
引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要...
一. 宏观概念 ASP.NET Core Middleware是在应用程序处理管道...
背景 在.Net和C#中运行异步代码相当简单,因为我们有时候需要...
HTTP基本认证 在HTTP中,HTTP基本认证(Basic Authenticatio...
1.Linq 执行多列排序 OrderBy的意义是按照指定顺序排序,连续...