1

Я пытаюсь создать сайт с несколькими арендаторами mvc 5, который использует одну базу данных и выделяет арендаторов по схеме на Sql Server. Я начал с шаблона Mvc 5 по умолчанию и обновил ApplicationDBContext, который предоставляется, чтобы взять строку, определяющую схему, которая будет использоваться для этого арендатора.Как обрабатывать аутентификацию в приложении с несколькими арендаторами MVC 5

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> 
{ 
    private string _tenantSchema; 
    public ApplicationDbContext(string tenantSchema) 
     : base("Dev", throwIfV1Schema: false) 
    { 
     _tenantSchema = tenantSchema; 
    } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.HasDefaultSchema(_tenantSchema); 
     base.OnModelCreating(modelBuilder); 
    } 

    public static ApplicationDbContext Create(string tenantSchema) 
    { 
     return new ApplicationDbContext(tenantSchema); 
    } 
} 

А потом в App_Start \ IdentityConfig.cs Я обновил Создать Метод ApplicationUserClass использовать первую часть стоимости Request.Host использовать как tenantSchema как так

public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var tenantSchema = context.Request.Host.Value.Split('.')[0]; 
     var ctx = new ApplicationDbContext(tenantSchema); 

     var userStore = new UserStore<ApplicationUser>(ctx); 
     var manager = new ApplicationUserManager(userStore); 

так если я должен войти в site1.mysite.dev, он будет аутентифицироваться против таблиц в схеме site1, это sql-сервер.

Когда я запускаю сайт и получаю доступ к нему с использованием подменю site1, он правильно использует схему site1 для аутентификации. Но если я изменил URL-адрес в адресной строке браузера и снова войду в систему, он все равно проверяет схему сайта1.

Как настроить приложение на использование схемы для проверки подлинности для каждого запроса?

+1

Вы отлажено и проверяется, будет ли Create вызываться по каждому запросу? Если да, то на самом деле у tenantSchema есть данные, которые вы ожидаете? Если он не вызывается по каждому запросу, вы неправильно настроили что-то неправильно, пожалуйста, покажите свой Startup.Auth –

ответ

1

Хотя код, который вы показали, должен выглядеть как работа (но трудно сказать, поскольку вы оставили другие ключевые части, такие как Startup.Auth), я бы не сделал этого таким образом. Я бы вместо того, чтобы изменить способ ApplicationDbContext.Create к этому:

public static ApplicationDbContext Create(
      IdentityFactoryOptions<ApplicationDbContext> options, IOwinContext context) 
{ 
    var tenantSchema = context.Request.Host.Value.Split('.')[0]; 
    return new ApplicationDbContext(tenantSchema); 
} 

Я бы тогда изменить мое Startup.Auth как таковой:

app.CreatePerOwinContext<ApplicationDbContext>(ApplicationDbContext.Create); <--- 
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create); 
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create); 

И все остальное оставьте по умолчанию. В частности:

public static ApplicationUserManager Create(
     IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
{ 
    var manager = new ApplicationUserManager(
        new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); 
    .... 

Однако ваша реальная проблема, скорее всего, что ваша модель строитель кэшируется в области приложения в первый раз, когда он будет создан. Это упоминается в документации здесь:

http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext.onmodelcreating(v=vs.113).aspx

Как правило, этот метод вызывается только один раз, когда первый экземпляр производного контекста создается. Модель для этого контекста затем кэшируется и предназначена для всех дополнительных экземпляров контекста в домене приложения. Это кэширование можно отключить, установив свойство ModelCaching на данный ModelBuidler, но обратите внимание, что это может серьезно ухудшить производительность. Дополнительный контроль над кешированием обеспечивается за счет использования классов DbModelBuilder и DbContextFactory.

Существует на самом деле хорошая дискуссия по этой самой теме, связанные с EF и использования многопользовательских (слишком долго, чтобы разработать здесь) более на CodePlex сайте EF:

https://entityframework.codeplex.com/discussions/462765