I have a c# blazor web application, which should authenticate users using the SignInManager. But the database to use is not known at design time, it depends on a URL parameter. So I can't use a connectionstring in the program.cs. In program.cs is only a reference to a main database. So I created a SingnInManager at runtime und try to use it. But the new created SignInManager always uses the main database from program.cs.
Here is the code I used:
var newConnectionString = "Data Source=...";DynamicDbContext activeDbContext = new DynamicDbContext(newConnectionString);using (var context = activeDbContext.ActiveDbContext){ ApplicationDbContext = context; var userStore = new UserStore<ApplicationUser>(context); var options = Options.Create(new IdentityOptions()); var passwordHasher = new PasswordHasher<ApplicationUser>(); var userValidator = new IUserValidator<ApplicationUser>[0]; var passwordValidator = new IPasswordValidator<ApplicationUser>[0]; var keyNormalizer = new UpperInvariantLookupNormalizer(); var errors = new IdentityErrorDescriber(); var services = new ServiceCollection().BuildServiceProvider(); var logger1 = ServiceProvider.GetRequiredService<ILogger<UserManager<ApplicationUser>>>(); var newUserManager = new UserManager<ApplicationUser>(userStore, options, passwordHasher, userValidator, passwordValidator, keyNormalizer, errors, services, logger1); var contextAccessor = ServiceProvider.GetRequiredService<IHttpContextAccessor>(); var claimsFactory = ServiceProvider.GetRequiredService<IUserClaimsPrincipalFactory<ApplicationUser>>(); var optionsAccessor = ServiceProvider.GetRequiredService<IOptions<IdentityOptions>>(); var logger = ServiceProvider.GetRequiredService<ILogger<SignInManager<ApplicationUser>>>(); var schemes = ServiceProvider.GetRequiredService<IAuthenticationSchemeProvider>(); var confirmation = ServiceProvider.GetRequiredService<IUserConfirmation<ApplicationUser>>(); var signInManager = new SignInManager<ApplicationUser>(newUserManager, contextAccessor, claimsFactory, optionsAccessor, logger, schemes, confirmation); var result = await signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: false);}Last line of code fails at runtime, because the main database is used and therefore tables are not found:SqlException: Invalid objektname "LoginUserClaims".
The context and newUserManager is tested and works fine with the newConnectionString and is using the expected database.
When I change the connectionstring used in program.cs to a specific one that is passed to the application by URL everything is fine, but this only works with that fixed database then and therefore can't be the solution.
program.cs
...var connectionString = builder.Configuration.GetConnectionString("DefaultConnection") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");builder.Services.AddDbContext<ApplicationDbContext>(options =>{ options.UseSqlServer(connectionString);});builder.Services.AddIdentityCore<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = false) .AddEntityFrameworkStores<ApplicationDbContext>() .AddSignInManager() .AddDefaultTokenProviders();...How to connect the signInManager to the dynamicaly creaded database connection? Any help is welcome.