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
Как я могу решить эту проблему?
Спасибо