繁体   English   中英

没有依赖注入的控制台应用程序的用户管理器

[英]User Manager for console app without Dependency Injection

我正在尝试在 .NET 6 中将用户管理器用于 C# 控制台应用程序,而无需依赖项注入的帮助。 我设法构建了一个用户管理器的实例,但是当我开始使用它时(为我的用户创建一个带有密码重置的 email),我得到这个错误:

没有注册名为“默认”的 IUserTwoFactorTokenProvider。

这是我在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);

这是运行用户管理器的方法:

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();
             }
         }
     }
}

我现在坚持这个并且不知道如何解决它。

我也尝试过手动添加 Token Provider 但这没有任何区别:

var identityBuilder = new IdentityBuilder(typeof(ApplicationUser), typeof(IdentityRole<string>), services);
identityBuilder.AddTokenProvider("Default", typeof(DataProtectorTokenProvider<ApplicationUser>));
services.AddTransient<UserManager<ApplicationUser>>();

错误消息“没有注册名为‘Default’的 IUserTwoFactorTokenProvider”是因为您缺少默认双因素令牌提供程序的配置。 要解决此问题,您需要在服务集合中为 UserManager 注册默认的双因素令牌提供程序。

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();
                }
            }
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM