Зарегистрированные пользовательские строки подключения в.NET Core
У меня есть приложение, которое использует базу данных идентичности для хранения пользователей и клиентов.
Каждый клиент имеет также отдельную базу данных со своими данными, и его строка подключения хранится в Customer
таблица в базе данных идентичности.
AspNetUsers
имеет поле, чтобы указать, к какому клиенту принадлежит пользователь (также идентификатор БД).
Я хочу назначить пользователю строку подключения, когда он входит в систему, и сделать ее доступной в приложении на время сеанса.
В настоящее время у меня есть модель клиента:
public partial class `Customer`
{
public int Id { get; set; }
public string Name { get; set; }
public int NoLicenses { get; set; }
public bool? Enabled { get; set; }
public string CustomerConnectionString { get; set; }
}
и модель пользователя:
public class ApplicationUser : IdentityUser
{
public string CustomerId { get; set; }
public bool? IsEnabled { get; set; }
// there ideally I'd have a connstring property
}
Модели отображают поля таблицы БД.
Я использую.NET Core 1.1 и EF Core.
1 ответ
С помощью шаблона разграничения ASP.NET Identity вы можете:
расширить класс ApplicationUser в
Models
папка:public class ApplicationUser : IdentityUser { public string CustomerId { get; set; } public bool? IsEnabled { get; set; } //add your custom claims public string CustomerConnectionString { get; set; } }
Добавьте свою собственную модель в
ApplicationDbContext
в папке данных:public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Customize the ASP.NET Identity model and override the defaults if needed. // For example, you can rename the ASP.NET Identity table names and more. // Add your customizations after calling base.OnModelCreating(builder); } public DbSet<Customer> Customers { get; set; } }
Синхронизируйте вашу базу данных: Add-Migration xxxx, затем выполните команду Update-Database в консоли диспетчера пакетов. Теперь у вас есть таблица клиентов и есть
CustomerConnectionString
колонка вAspNetUsers
Таблица.Создайте собственную реализацию IUserClaimsPrincipalFactory, унаследовав реализацию по умолчанию для генерации ClaimsPrincipal от вашего пользователя:
public class AppClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole> { public AppClaimsPrincipalFactory( UserManager<ApplicationUser> userManager , RoleManager<IdentityRole> roleManager , IOptions<IdentityOptions> optionsAccessor) : base(userManager, roleManager, optionsAccessor) { } public async override Task<ClaimsPrincipal> CreateAsync(ApplicationUser user) { var principal = await base.CreateAsync(user); if (!string.IsNullOrWhiteSpace(user.CustomerId)) { ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim("customid", user.CustomerId) }); } if (!string.IsNullOrWhiteSpace(user.CustomerConnectionString)) { ((ClaimsIdentity)principal.Identity).AddClaims(new[] { new Claim("CustomerConnectionString", user.CustomerConnectionString) }); } return principal; } }
Зарегистрируйте пользовательскую фабрику, которую вы только что создали, в своем классе запуска приложения после добавления службы идентификации:
// Add framework services. services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddScoped<Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory<ApplicationUser>, AppClaimsPrincipalFactory>();
Тогда вы можете получить доступ к претензиям, как:
var connectString = User.Claims.FirstOrDefault(c => c.Type == "CustomerConnectionString").Value;
Измените создание / редактирование пользовательского представления / контроллера, добавьте раскрывающийся список клиентов в представлении, получите пользовательский идентификатор в
Register
функция вAccountController
запросите connecting String пользовательского из базы данных и сохраните вApplicationUser
объект:var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password);