首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在多租户MVC 5应用程序中进行身份验证

如何在多租户MVC 5应用程序中进行身份验证
EN

Stack Overflow用户
提问于 2014-11-27 04:37:32
回答 1查看 1.1K关注 0票数 1

我正在尝试构建一个多租户mvc 5站点,它使用单个数据库,并通过Sql Server中的模式来区分租户。我从默认的Mvc 5模板开始,并更新了提供的ApplicationDBContext,以接受一个字符串,该字符串指定租户要使用的模式,如下所示。

代码语言:javascript
运行
复制
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的Create方法,将Request.Host值的第一部分用作tenantSchema,如下所示

代码语言:javascript
运行
复制
 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模式中的表进行身份验证。

当我启动站点并使用site1子域访问它时,它正确地使用site1架构对我进行身份验证。但是,如果我在浏览器地址栏中更改url并再次登录,它仍然会根据site1模式进行验证。

如何将应用程序配置为更正模式以检查每个请求的身份验证?

EN

回答 1

Stack Overflow用户

发布于 2014-11-27 06:00:49

虽然您展示的代码应该可以工作(但很难判断,因为您遗漏了其他关键部分,如Startup.Auth),但我不会这样做。相反,我会将您的ApplicationDbContext.Create方法改为:

代码语言:javascript
运行
复制
public static ApplicationDbContext Create(
           IdentityFactoryOptions<ApplicationDbContext> options, IOwinContext context)
{
    var tenantSchema = context.Request.Host.Value.Split('.')[0];
    return new ApplicationDbContext(tenantSchema);
}

然后,我将修改我的Startup.Auth:

代码语言:javascript
运行
复制
app.CreatePerOwinContext<ApplicationDbContext>(ApplicationDbContext.Create); <---
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

其他一切都是默认的。具体地说:

代码语言:javascript
运行
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27163152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档