首页 > 解决方案 > ASP Net Core SignInManager 未登录

问题描述

我也有一个基于 .Net Core 3.1 和 EF Core 的简单 Web api 项目。我尝试遵循 DDD 模式,并且我的应用程序的结构如下(单独的项目):

我的 ApplicationDbContext 存储在我的 CofigureServices 下的EF Project用途如下所示(这是一个 Intranet 应用程序,因此不需要确认帐户):DefaultIdentityWeb Api Project

 services.AddDbContext<ApplicationDbContext>();
 services.AddDefaultIdentity<UserDB>(options => options.SignIn.RequireConfirmedAccount = false)
         .AddRoles<IdentityRole>()
         .AddEntityFrameworkStores<ApplicationDbContext>()
         .AddDefaultTokenProviders();

然后,当我尝试登录应用程序(通过 LoginController)时,我创建了以下简单方法:

[HttpGet("signin")]
[MapToApiVersion("1.0")]
public async Task<bool> SignIn([FromQuery]string username, [FromQuery] string password)
{
    var result = await signInManager.PasswordSignInAsync(username, password, false, false);
    return result.Succeeded;
}

当我从我的 Web Api 应用程序创建帐户时,一切正常,正如预期的那样。但是在我的情况下,在目标服务器(将部署此应用程序)上,我无权安装自定义工具(例如 EF Core 工具),因此为了在目标服务器上进行迁移(以及控制初始种子)我决定创建一个单独的控制台应用程序EF Migrator Project(在同一个解决方案中,并且也依赖于我的 ef 核心),如下所示:

静态异步任务 Main(string[] args) { IConfigurationRoot config = new ConfigurationBuilder() .AddJsonFile($"appsettings.json", true, true) .AddJsonFile($"appsettings.Development.json", true, true) .Build ();

        IServiceProvider serviceProvider;

        var services = new ServiceCollection();
        ConfigureServices(services, config);
        serviceProvider = services.BuildServiceProvider();

        var context = serviceProvider.GetRequiredService<ApplicationDbContext>();

        context.Database.Migrate();
        await SeedRoles(context, serviceProvider);
        await SeedUsers(context, serviceProvider);
    }



private static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
    {
        services.AddSingleton<IConfiguration>(configuration);
        services.AddDbContext<ApplicationDbContext>();


        // Register UserManager & RoleManager
        services.AddIdentityCore<UserDB>()
           .AddRoles<IdentityRole>()
           .AddEntityFrameworkStores<ApplicationDbContext>();


        // UserManager & RoleManager require logging and HttpContext dependencies
        services.AddLogging();
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

然后我在数据库中创建一个用户,如下所示(简化):

 static async Task SeedUsers(ApplicationDbContext context, IServiceProvider serviceProvider)
        {
            if (await context.Users.AnyAsync())
                return;

            var userManager = serviceProvider.GetRequiredService<UserManager<UserDB>>();
            var roleManager = serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();

            var result = await userManager.CreateAsync(new UserDB() { Id = "fakeuser", ... }, "fakepassword");

            var userAddedResult = await userManager.FindByEmailAsync(result);
            await userManager.AddToRoleAsync(userAddedResult , "ADMIN");
        }

现在,当我打开 SQL Server 时,我可以清楚地看到我的用户已创建并存储在数据库中。但是,当我切换回我的 ASP.NET 应用程序并尝试登录(使用相同的凭据)时,它现在禁止我并且看起来它无法识别我(登录结果为假)。

我的设置中有什么遗漏的吗?对我来说,这似乎是我的控制台应用程序从我的 ASP.NET 端无法识别的自己的上下文(可能使用自定义哈希算法)创建了一个新用户?

标签: c#asp.net-coreauthentication.net-coreentity-framework-core

解决方案


最后问题出在我的EF Migrator设置上。我正在通过以下方式添加新用户:

var result = await userManager.CreateAsync(new UserDB() { Id = adminEmail, Name = "Admin", **UserName = "Admin"**, NormalizedUserName = "Admin", Email = adminEmail }, adminPassword);

而且我不知道登录是通过用户名完成的。一旦我更改UserName为实际的电子邮件(我正在通过它进行登录),它就像一个魅力。它应该是这样的:

var result = await userManager.CreateAsync(new UserDB() { Id = adminEmail, Name = "Admin", **UserName = adminEmail**, NormalizedUserName = "Admin", Email = adminEmail }, adminPassword);

此外,我稍微更新了我的设置代码,因此它现在与我在实际WebAPI项目中的内容保持同步:

 private static void ConfigureServices(IServiceCollection services, IConfiguration configuration)
        {
            services.AddSingleton<IConfiguration>(configuration);
            services.AddDbContext<ApplicationDbContext>();


            // Register UserManager & RoleManager
            services.AddDefaultIdentity<UserDB>(options => options.SignIn.RequireConfirmedAccount = false)
               .AddRoles<IdentityRole>()
               .AddEntityFrameworkStores<ApplicationDbContext>();

            services.Configure<IdentityOptions>(options =>
            {
                ... other setup
            });

            // UserManager & RoleManager require logging and HttpContext dependencies
            services.AddLogging();
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        }

推荐阅读