I am trying to use the User Manager for a C# console app in .NET 6 without the help of dependency injection. I manage to construct an instance of the User Manager but when I get to using it (create an email with password reset for my users), I get this error:
No IUserTwoFactorTokenProvider named 'Default' is registered.
Here is where I initialize the User Manager in Program.cs
:
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
IServiceCollection services = new ServiceCollection();
services.AddTransient<UserManager<ApplicationUser>>();
var connectionStrings = config.GetSection("ConnectionStrings");
var messagingConnectionString = connectionStrings.GetValue<string>("Messaging");
AgentConfigDTO appSettingsDTO = new AgentConfigDTO()
{
....
};
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionStrings.ToString(),
sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure(
maxRetryCount: 5,
maxRetryDelay: TimeSpan.FromSeconds(30),
errorNumbersToAdd: null);
}
));
// Register UserManager & RoleManager
services.AddIdentity<IdentityUser, IdentityRole>();
services.AddIdentity<ApplicationUser, IdentityRole>(
options =>
{
options.Tokens.ProviderMap.Add("Default", new TokenProviderDescriptor(typeof(IUserTwoFactorTokenProvider<ApplicationUser>)));
})
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddTransient<IUserStore<IdentityUser>, UserStore<IdentityUser>>();
services.AddTransient<UserManager<IdentityUser>>();
IServiceProvider serviceProvider = services.BuildServiceProvider();
var optionsBuilderApplication = new DbContextOptionsBuilder<ApplicationDbContext>();
var _applicationContext = new ApplicationDbContext(optionsBuilderApplication.UseSqlServer(connectionStrings.ToString()).Options);
IUserStore<ApplicationUser> store = new UserStore<ApplicationUser>(_applicationContext);
UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(store, null, new PasswordHasher<ApplicationUser>(), null, null, null, null, serviceProvider, null);
// UserManager & RoleManager require logging and HttpContext dependencies
services.AddLogging();
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
new ReportAgent(appSettingsDTO, messagingConnectionString, userManager).RunAsConsole(args);
And this is the method that runs the User Manager:
public void CheckingPasswords()
{
try
{
var date = DateTime.Now.AddMonths(-3);
var userList = _applicationContext.Users.Where(t => t.PasswordExpiry != null && t.PasswordExpiry <= DateTime.Now.AddMonths(-3) && t.Deleted == false && t.PortalAccessEnabled == true).ToList();
if (userList.Count > 0)
{
// Create email
foreach (var user in userList)
{
// Lock user out of the account
user.PortalAccessEnabled = false;
_applicationContext.Update(user);
_applicationContext.SaveChanges();
// Create email
// Exception is thrown on this line of code
var code = _userManager.GeneratePasswordResetTokenAsync(user).ToString();
var url = .
var callbackUrl = url.Replace("[[id]]", user.Id).Replace("[[code]]", code);
Email email = new()
{
...
};
_dbContext.Add(email);
_dbContext.SaveChanges();
}
}
}
}
I am now stuck with this and have no idea how to fix it.
I've also tried manually adding in the Token Provider but that didn't make any difference:
var identityBuilder = new IdentityBuilder(typeof(ApplicationUser), typeof(IdentityRole<string>), services);
identityBuilder.AddTokenProvider("Default", typeof(DataProtectorTokenProvider<ApplicationUser>));
services.AddTransient<UserManager<ApplicationUser>>();
The error message "No IUserTwoFactorTokenProvider named 'Default' is registered" is because you are missing the configuration for the default two-factor token provider. To resolve this, you need to register the default two-factor token provider for UserManager in the services collection.
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddTransient<IUserStore<ApplicationUser>, UserStore<ApplicationUser>>();
services.AddTransient<UserManager<ApplicationUser>>();
services.AddLogging();
services.AddHttpContextAccessor();
}
}
public class ConsoleApp
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly ApplicationDbContext _applicationContext;
public ConsoleApp(UserManager<ApplicationUser> userManager, ApplicationDbContext applicationContext)
{
_userManager = userManager;
_applicationContext = applicationContext;
}
public void CheckingPasswords()
{
try
{
var date = DateTime.Now.AddMonths(-3);
var userList = _applicationContext.Users.Where(t => t.PasswordExpiry != null && t.PasswordExpiry <= DateTime.Now.AddMonths(-3) && t.Deleted == false && t.PortalAccessEnabled == true).ToList();
if (userList.Count > 0)
{
//Create email
foreach (var user in userList)
{
// Lock user out of the account
user.PortalAccessEnabled = false;
_applicationContext.Update(user);
_applicationContext.SaveChanges();
//Create email
var code = _userManager.GeneratePasswordResetTokenAsync(user).Result;
var url = .
var callbackUrl = url.Replace("[[id]]", user.Id).Replace("[[code]]", code);
Email email = new()
{
...
};
_dbContext.Add(email);
_dbContext.SaveChanges();
}
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.