2009-11-09 17 views
8

我想設置一個多租戶ASP.NET MVC應用程序。理想情況下,這個應用程序將有一個路線與{tenant}/{controller}/{action}/{id},每個tenant代表應用程序的(簡單獨立的多用戶帳戶)使用ASP.NET MVC設置路線{tenant}/{controller}/{action}/{id}?

的細粒度細節如何做到這一點仍然相當不清楚我的邏輯實例。可以使用ASP.NET MVC設置這種多租戶方案的任何指南?

回答

12

我目前正在使用ASP.Net MVC,Forms Authentication和SQL Provider for Membership/Roles/Profile進行類似的項目。這裏是我採取的辦法:

  1. 註冊爲`{租戶}/{控制器}/{行動}/{ID}

  2. 更改FormsAuthenticationService的默認行爲自帶的默認路由與標準的MVC模板。它應該設置身份驗證票據的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文件做一些租戶的安全檢查,並允許租戶之間的用戶partioning在一個會員數據庫

    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. 分區每個租戶數據。這裏有兩種選擇:

    4a。爲每個租戶使用單獨的數據庫。這爲租戶提供了最佳的數據安全性。在共享成員資格數據庫中,爲每個租戶添加一個以獨特appid爲關鍵字的表,並使用此表存儲和檢索基於當前租戶的連接字符串。

    4b。將所有數據存儲在一個數據庫中,並將每個表格鍵入唯一租戶ID。這爲租戶提供的數據安全性稍低,但只使用一個SQL Server許可證。

+2

對不起,過期的回覆,但我正在研究類似的東西,我認爲你的解決方案可能會起作用,但是文檔說,只有一個默認的提供者可以進入服務器。所以,我認爲設置應用程序名稱可能是一個競爭條件。 –

+0

CShipley,你是對的。當我自己使用這個解決方案時,我幾乎瘋了,試圖解決一旦我擁有來自不同租戶的併發用戶的問題。我認爲要從頭開始編寫認證部分或實現您自己的成員資格提供者。我選擇移動到每個租戶的應用程序的單獨實例,直到我可以獲得自定義身份驗證方案的詳細信息。 –

+0

您如何處理可以代表多個承租人行事的用戶? –

2

你會犯錯findtheselinksuseful

+0

鏈接的問題確實是相關的,但不幸的是沒有很好的答案。其實,只有相關的帖子鏈接到另一個帖子,甚至不太相關的答案:-( –

+0

那sux。我想我會等到你找到答案然後我會用你發現的然後。:D –

+0

謝謝,這些鏈接都很棒! –