[英]Changing ASP.NET Core 2.0 Identity Connection String in Controller
我正在创建一个多租户结构的Web应用程序。 因此,每个用户请求将根据主机名(每个租户使用不同的数据库)锁定该用户特定的租户。我可以设置一般上下文的连接字符串,但我现在不知道如何更改连接ASP.NET Core 2.0标识对象的字符串。
我看到他们让我们这样做的默认方式是在StartUp.cs中设置UseAuthentication()。 然后,当调用控制器时,DI然后设置UserManager和SignInManager对象。 我假设我需要在每个控制器构造函数中创建新的UserManager和SignInManager对象,传递该租户的特定连接字符串(根本不使用DI)。
有什么想法吗?
澄清:
我希望弄清楚是否可以通过依赖注入将传递的标识对象的数据库连接字符串更改为控制器。
// Startup class of asp.net core 2
public void ConfigureServices(IServiceCollection services)
{
services.AddMultitenancy<Tenant, TenantResolver>();
string accountsConnection = configuration.GetConnectionString("AccountsConnectionString");
services.AddScoped<LicenseManager>();
services.AddScoped<AccountManager>();
services.AddEntityFrameworkSqlServer()
.AddDbContext<AccountsContext>(options =>
{
options.UseSqlServer(accountsConnection);
})
.AddDbContext<MasterDataContext>(options => options.UseSqlServer(masterdataConnection))
.AddDbContext<DataContext>();
services.AddMvc();
}
// Tenantresolver which get's the connectionstring from the claims. (seperate file/class)
// On authentication i create several claims with one claim with the connectionstring per user.
// I use a seperate accounts database where all the tenants are saved which each of them has his own connectionstring
public class TenantResolver : MemoryCacheTenantResolver<Tenant>
{
private readonly AccountsContext Context;
public TenantResolver(AccountsContext context, IMemoryCache cache, ILoggerFactory logger)
:base(cache, logger)
{
Context = context;
}
protected override string GetContextIdentifier(HttpContext context)
{
return context.User.Claims.Where(r => r.Type == ClaimTypes.AccountIdType).Select(s => s.Value).SingleOrDefault();
}
protected override IEnumerable<string> GetTenantIdentifiers(TenantContext<Tenant> context)
{
return new[] { context.Tenant.Tenant_Id.ToString() };
}
protected override Task<TenantContext<Tenant>> ResolveAsync(HttpContext context)
{
TenantContext<Tenant> tenantContext = null;
string claim = context.User.Claims.Where(r => r.Type == ClaimTypes.AccountIdType).Select(s => s.Value).SingleOrDefault();
var tenant = Context.Accounts
.Where(q => q.IsActive == true && q.Account_Id.ToString() == claim)
.Select(s => new Tenant(s.Account_Id, s.DataStore.DatabaseConnection))
.FirstOrDefault();
if (tenant != null)
{
tenantContext = new TenantContext<Tenant>(tenant);
}
return Task.FromResult(tenantContext);
}
}
// Tenant class where i save the info needed.
public class Tenant
{
public Tenant(
Guid tenant_id,
string database_ConnectionString)
{
Tenant_Id = tenant_id;
Database_ConnectionString = database_ConnectionString;
}
public Guid Tenant_Id { get; set; }
public string Database_ConnectionString { get; set; }
}
// DbContext class which uses the tenant and links the connectionstring to the current tenant.
public class DataContext : DbContext
{
private readonly Tenant Tenant;
public DataContext(DbContextOptions<DataContext> options, Tenant tenant)
: base(options)
{
this.Tenant = tenant;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (Tenant != null)
{
optionsBuilder.UseSqlServer(Tenant.Database_ConnectionString);
}
base.OnConfiguring(optionsBuilder);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.