Почему сбой входа в систему для сеяных пользователей в удостоверении ядра aspnet? - PullRequest
0 голосов
/ 21 января 2019

Ciao, Я создаю идентификационный сервер. Я использую эти технологии:

  • ASP.NET Core 2.2
  • Идентификация ASP.NET (с EF Core и MariaDB)
  • IdentityServer4

Я настроил сеялку для пользователей удостоверения aspnet. Ниже мой код создания пользователя:

using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Security.Claims;

namespace MyOrganization.IdentityServer.API.Data.Seed
{
    public class AspNetIdentitySeeder
    {
        public static void EnsureSeedData(string connectionString)
        {
            // adding IdentityDbContext to ServiceCollection...
            ServiceCollection services = new ServiceCollection();
            services.AddDbContext<IdentityDbContext>(options =>
            {
                options.UseMySql(connectionString, sql => sql.MigrationsAssembly(typeof(AspNetIdentitySeeder).Assembly.FullName));
            });

            // adding identity...
            services.AddIdentity<IdentityUser, IdentityRole>()
                .AddEntityFrameworkStores<IdentityDbContext>()
                .AddDefaultTokenProviders();

            // seeding database...
            using (ServiceProvider serviceProvider = services.BuildServiceProvider())
            {
                using (IServiceScope scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
                {
                    IdentityDbContext context = scope.ServiceProvider.GetService<IdentityDbContext>();
                    EnsureSeedData(scope, context);
                }
            }
        }

        private static void EnsureSeedData(IServiceScope scope, IdentityDbContext context)
        {
            // applying all pending changes...
            context.Database.Migrate();

            // adding users...
            UserManager<IdentityUser> userMgr = scope.ServiceProvider.GetRequiredService<UserManager<IdentityUser>>();

            AddUser(
                userMgr,
                "alice",
                "Alice Alice",
                "Alice",
                "Alice",
                "Alice@email.com",
                "true",
                "",
                ""
                );
        }

        private static void AddUser(UserManager<IdentityUser> userMgr, string username, string name, string givenName, string familyName, string email, string emailVerified, string webSite, string address)
        {
            var user = userMgr.FindByNameAsync(username).Result;
            if (user == null)
            {
                user = new IdentityUser
                {
                    UserName = email,
                    Email = email,
                    EmailConfirmed = true
                };
                var result = userMgr.CreateAsync(user, "LaMiaSuperPassword$").Result;
                if (!result.Succeeded)
                {
                    throw new Exception(result.Errors.First().Description);
                }

                result = userMgr.AddClaimsAsync(user, new Claim[]{
                        new Claim(JwtClaimTypes.Name, name),
                        new Claim(JwtClaimTypes.GivenName, givenName),
                        new Claim(JwtClaimTypes.FamilyName, familyName),
                        new Claim(JwtClaimTypes.Email, email),
                        new Claim(JwtClaimTypes.EmailVerified, emailVerified, ClaimValueTypes.Boolean),
                        new Claim(JwtClaimTypes.WebSite, webSite),
                        new Claim(JwtClaimTypes.Address, address, IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)
                    }).Result;
                if (!result.Succeeded)
                {
                    throw new Exception(result.Errors.First().Description);
                }
                Console.WriteLine($"{username} created.");
            }
            else
            {
                Console.WriteLine($"{username} already exists.");
            }
        }
    }
}

На самом деле моя проблема в том, что когда я пытаюсь войти в систему с отобранным пользователем, логин не работает, но если я создаю пользователя во время выполнения, логин работает правильно. Ниже моего Startup.cs код:

using IdentityServer4;
using IdentityServer4.Quickstart.UI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Reflection;
using MyOrganization.IdentityServer.API.Data.Contexts;

namespace MyOrganization.IdentityServer.API
{
    public class Startup
    {
        public IConfiguration Configuration { get; }
        public IHostingEnvironment Environment { get; }

        public Startup(IConfiguration config, IHostingEnvironment env)
        {
            Configuration = config;
            Environment = env;
        }

        public void ConfigureServices(IServiceCollection services)
        {
            // configuring basics (mvc, cors, iis express)...
            services.AddMvc().SetCompatibilityVersion(Microsoft.AspNetCore.Mvc.CompatibilityVersion.Version_2_1);
            services.AddCors(setup =>
            {
                setup.AddDefaultPolicy(config =>
                {
                    config.AllowAnyOrigin();
                    config.AllowAnyMethod();
                    config.AllowAnyHeader();
                });
            });
            services.Configure<IISOptions>(options =>
            {
                options.AutomaticAuthentication = false;
                options.AuthenticationDisplayName = "Windows";
            });

            // configuring dependency injections...
            services.AddDbContext<IdentityDbContext>(options =>
                options.UseMySql(Configuration.GetConnectionString("IdentityDefaultConnection")));

            services.AddDefaultIdentity<IdentityUser>()
                .AddEntityFrameworkStores<IdentityDbContext>()
                .AddDefaultTokenProviders();


            // configuring identity server...
            string connectionString = Configuration.GetConnectionString("DefaultConnection");
            string migrationsAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;

            IIdentityServerBuilder identityServer = services.AddIdentityServer(options =>
            {
                options.Events.RaiseErrorEvents = true;
                options.Events.RaiseInformationEvents = true;
                options.Events.RaiseFailureEvents = true;
                options.Events.RaiseSuccessEvents = true;
            })
                //.AddTestUsers(TestUsers.Users)
                // this adds the config data from DB (clients, resources, CORS)
                .AddConfigurationStore(options =>
                {
                    options.ConfigureDbContext = builder => builder.UseMySql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
                })
                // this adds the operational data from DB (codes, tokens, consents)
                .AddOperationalStore(options =>
                {
                    options.ConfigureDbContext = builder => builder.UseMySql(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));

                    // this enables automatic token cleanup. this is optional.
                    options.EnableTokenCleanup = true;
                })
                .AddAspNetIdentity<IdentityUser>();

            // configuring autentication...
            services.AddAuthentication();

            if (Environment.IsDevelopment())
            {
                identityServer.AddDeveloperSigningCredential();
            }
            else
            {
                throw new Exception("need to configure key material");
            }
        }

        public void Configure(IApplicationBuilder app)
        {
            if (Environment.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseDatabaseErrorPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }

            app.UseCors();
            app.UseIdentityServer();
            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
        }
    }
}

[EDIT]

Заполнение выполняется с помощью CLI ядра dotnet, ниже моего Program.cs:

using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
using System;
using System.Linq;
using MyOrganization.IdentityServer.API.Data.Seed;

namespace MyOrganization.IdentityServer.API
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.Title = "IdentityServer4.EntityFramework";

            var seed = args.Contains("/seed");
            if (seed)
            {
                args = args.Except(new[] { "/seed" }).ToArray();
            }

            var host = CreateWebHostBuilder(args).Build();

            if (seed)
            {
                var config = host.Services.GetRequiredService<IConfiguration>();
                var connectionString = config.GetConnectionString("DefaultConnection");
                var connectionStringAspNetIdentity = config.GetConnectionString("IdentityDefaultConnection");
                IdentityServerSeeder.EnsureSeedData(connectionString);
                AspNetIdentitySeeder.EnsureSeedData(connectionStringAspNetIdentity);
                return;
            }

            host.Run();
        }

        public static IWebHostBuilder CreateWebHostBuilder(string[] args)
        {
            return WebHost.CreateDefaultBuilder(args)
                    .UseStartup<Startup>()
                    .UseSerilog((context, configuration) =>
                    {
                        configuration
                            .MinimumLevel.Debug()
                            .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
                            .MinimumLevel.Override("System", LogEventLevel.Warning)
                            .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
                            .Enrich.FromLogContext()
                            .WriteTo.File(@".\Log\identityserver4_log.txt")
                            .WriteTo.Console(outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate);
                    });
        }
    }
}

Для посева я использую команду:

dotnet run /seed

Как я могу решить эту проблему?

Спасибо

...