我已经开始学习.NET CORE,并且我想实现基本的用户身份验证和授权。我尝试创建基于Onion Architecture的基础应用程序,因此创建了对其他项目的引用。现在,它看起来像这样:
Project.Core(我的数据库带有IdentityDbContext)-> Project.Data-> Project.Services-> Project.Ui(在这里,我尝试了 在此处实施Auth系统)
我在编译过程中没有收到错误消息,但是在运行整个应用程序之后却收到了一条巨大的错误消息。至少有5个例外。
我应该实施其他服务吗?如果是,在哪里?用IDesignTimeDbContextFactory
创建这样的数据库有效吗?
请在下面也找到代码示例。
User.cs (Project.Core)
using System;
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
namespace BeerGame.Core.Models
{
public class User : IdentityUser
{
[Required]
[MaxLength(200)]
public string Nick {get; protected set;}
[Required]
[MaxLength(200)]
public String Name { get; set; }
[Required]
[MaxLength(250)]
public String Surname { get; set; }
[Required]
[MaxLength(250)]
public string Password {get; protected set;}
public User(string nick, string name, string surname, string email, string password)
{
Nick = nick;
Name = name;
Surname = surname;
Password = password;
Email = email;
}
}
}
DbUserContext.cs (Project.Core)
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.EntityFrameworkCore.Design;
using Microsoft.EntityFrameworkCore;
using BeerGame.Core.Models;
using System.IO;
namespace BeerGame.Core.Data
{
public class UserIdentityDbContext : IdentityDbContext
{
public UserIdentityDbContext(){}
public UserIdentityDbContext(DbContextOptions<UserIdentityDbContext> options): base(options) {}
public DbSet<User> User {get; set;}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Server=localhost;Database=master;Trusted_Connection=True;");
}
}
public class UserIdentityDesignTimeDbContextFactory : IDesignTimeDbContextFactory<UserIdentityDbContext>
{
public UserIdentityDbContext CreateDbContext(string[] args)
{
IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile(@Directory.GetCurrentDirectory() + "/../BeerGame.Ui/appsettings.json")
.Build();
var builder = new DbContextOptionsBuilder<UserIdentityDbContext>();
var connectionString = configuration.GetConnectionString("DatabaseConnection");
builder.UseSqlServer(connectionString);
return new UserIdentityDbContext(builder.Options);
}
}
}
Startup.cs (Project.Ui)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using BeerGame.Ui.Hubs.Room;
using Microsoft.AspNetCore.SignalR;
using BeerGame.Core.Data;
using BeerGame.Core.Models;
namespace BeerGame.Ui
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDefaultIdentity<User>()
.AddEntityFrameworkStores<UserIdentityDbContext>()
.AddDefaultTokenProviders()
.AddDefaultUI();
services.Configure<IdentityOptions>(options => {
// Password settings.
options.Password.RequireDigit = true;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = true;
options.Password.RequireUppercase = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
options.Lockout.MaxFailedAccessAttempts = 5;
options.Lockout.AllowedForNewUsers = true;
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
options.User.RequireUniqueEmail = false;
});
services.ConfigureApplicationCookie(options => {
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(5);
options.LoginPath = "/User/Login";
options.AccessDeniedPath = "/User/AccessDenied";
options.SlidingExpiration = true;
});
services.AddControllersWithViews();
services.AddRazorPages();
services.AddSignalR();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthorization();
app.UseAuthentication();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "room",
pattern: "{controller=Room}/{action=Main}/{id?}"
);
endpoints.MapControllerRoute(
name: "user",
pattern : "{controller=User}/{action=Main}/{id?}"
);
endpoints.MapHub<RoomHub>("/RoomHub");
});
}
}
}
谢谢!