[英]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.