2009-11-09 1 views
8

Я хотел бы настроить приложение ASP.NET MVC с несколькими арендаторами. В идеале это приложение будет иметь маршрут с {tenant}/{controller}/{action}/{id}, каждый tenant, представляющий логический экземпляр приложения (просто независимые многопользовательские учетные записи)Настройка маршрута {арендатора}/{controller}/{действие}/{id} с помощью ASP.NET MVC?

Подробные сведения о том, как это все еще неясно для меня. Любое руководство, доступное для настройки такой многопользовательской схемы с ASP.NET MVC?

ответ

12

В настоящее время я работаю над аналогичным проектом с использованием ASP.Net MVC, аутентификации форм и поставщиков SQL для членства/роли/профиля. Вот подход, который я беру:

  1. Регистрация маршрут по умолчанию, как `{арендатора}/{контроллер}/{действие}/{идентификатор}

  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. Partition каждый арендаторы данных. Вот два варианта:

    4a. Используйте отдельную базу данных для каждого арендатора. Это обеспечивает лучшую защиту данных для ваших арендаторов. В базе данных с общим членством добавьте таблицу, в которой используется уникальное приложение для каждого арендатора, и используйте эту таблицу для хранения и извлечения строки подключения на основе текущего арендатора.

    4b. Храните все данные в одной базе данных и запишите каждую таблицу в уникальный идентификатор арендатора. Это обеспечивает немного меньшую безопасность данных для ваших арендаторов, но использует только одну лицензию SQL Server.

+2

Извините за устаревший ответ, но Я работаю над чем-то подобным, и я думаю, что ваше решение может работать, однако документы говорят, что для всех запросов, поступающих на сервер, есть только один поставщик по умолчанию. Итак, я думаю, что установка имени приложения может быть условием гонки. –

+0

CShipley, вы абсолютно правы. Когда я сам использовал это решение, я почти сходил с ума, пытаясь устранить проблемы, когда у меня были одновременно пользователи из разных арендаторов. Я думаю, что путь состоит в том, чтобы написать часть аутентификации с нуля или реализовать собственный поставщик членства. Я решил перейти к отдельному экземпляру приложения для каждого арендатора, пока я не получу детали схемы пользовательской аутентификации. –

+0

Как вы обрабатываете пользователя, который может действовать от имени более чем одного арендатора? –

2

Вы проверите findtheselinksuseful.

+0

Связанный с этим вопрос действительно, но, к сожалению, нет хороших ответов. На самом деле, единственное релевантное сообщение ссылается на еще один пост, с еще менее релевантными ответами :-( –

+0

Что ж, думаю, я подожду, пока вы не найдете ответ, и я буду использовать то, что вы найдете тогда.: D –

+0

Спасибо, эти ссылки отличные! –