StartUp.cs
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using System; using System.IO; namespace NetCoreTestMVC2 { 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.Configure<CookiePolicyOptions>(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); string connectionString = Configuration["ConnectionStrings:DefaultConnection"]; services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); services.AddDbContext<DataContext>(options => { options.UseSqlServer(connectionString); }); //private readonly SignInManager<IdentityUser> _signInManager; //private readonly UserManager<IdentityUser> _userManager; services.AddScoped<IRepository<Student>, StudentService>(); #region 用户系统 //注册用户数据库,前面指定过一个DbContext了,这里add-migration的时候要指定DbContext //add-migration add-user-dbcontext -Context IdentityDbContext //合并Assembly //update-database -Context IdentityDbContext services.AddDbContext<IdentityDbContext>(options => { options.UseSqlServer(connectionString, b => b.MigrationsAssembly("NetCoreTestMVC2")); }); //注册用户服务 services.AddDefaultIdentity<IdentityUser>().AddEntityFrameworkStores<IdentityDbContext>(); //配置用户名、密码规则 services.Configure<IdentityOptions>(options => { // Password settings. options.Password.RequireDigit = false; options.Password.RequireLowercase = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; options.User.RequireUniqueEmail = false; }); #endregion } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseStaticFiles(new StaticFileOptions { RequestPath = "/node_modules", FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "node_modules")) }); app.UseCookiePolicy(); //使用身份验证 app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } } }
AccountController.cs
using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using NetCoreTestMVC2.Models; namespace NetCoreTestMVC2.Controllers {
[Authorize(Roles = "Admin")] public class AccountController : Controller { private readonly SignInManager<IdentityUser> _signInManager; private readonly UserManager<IdentityUser> _userManager; public AccountController(SignInManager<IdentityUser> signInManager, UserManager<IdentityUser> userManager) { _signInManager = signInManager; _userManager = userManager; } public IActionResult Login() { return View(); } [HttpPost] public async Task<IActionResult> Login(LoginInputDto dto) { if (!ModelState.IsValid) { return View(dto); } var user = await _userManager.FindByNameAsync(dto.UserName); if (user != null) { var result = await _signInManager.PasswordSignInAsync(user, dto.Password, false, false); if (result.Succeeded) { return RedirectToAction("Index", "Home"); } } ModelState.AddModelError("", "用户名、密码不正确"); return View(dto); } public IActionResult Register() { return View(); } [HttpPost] public async Task<IActionResult> Register(RegisterInputDto dto) { if (!ModelState.IsValid) { return View(dto); } var user = await _userManager.FindByNameAsync(dto.UserName); if (user != null) { ModelState.AddModelError("", "用户名已存在"); return View(dto); } else { user = new IdentityUser { UserName = dto.UserName }; var result = await _userManager.CreateAsync(user, dto.Password); if (result.Succeeded) { return RedirectToAction("Index", "Home"); } } return View(dto); } [HttpPost] public async Task<IActionResult> Logout() { await _signInManager.SignOutAsync(); return RedirectToAction("Index", "Home"); } } }
前端判断
@*前端注入SignInManager<IdentityUser>*@ @using Microsoft.AspNetCore.Identity @inject SignInManager<IdentityUser> _signInManager @*判断是否登录*@ @if (_signInManager.IsSignedIn(User)) { <li> <form asp-controller="Account" asp-action="Logout" method="post"> <button class="nav-link text-dark" type="submit">Logout</button> </form> </li> } else { <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Register">Register</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="" asp-controller="Account" asp-action="Login">Login</a> </li> }
文档:https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/identity?view=aspnetcore-3.1&tabs=visual-studio
扩展IdentityUser示例
public class ApplicationUser : IdentityUser { [MaxLength(18)] public string IdCardNo { get; set; } [DataType(DataType.Date)] public DateTime BirthDay { get; set; }
public virtual ICollection<IdentityUserClaim<string>> Claims { get; set; }
public virtual ICollection<IdentityUserLogin<string>> Logins { get; set; }
public virtual ICollection<IdentityUserToken<string>> Tokens { get; set; }
public virtual ICollection<IdentityUserRole<string>> UserRoles { get; set; }
} //对应DbContext也要修改 public class ApplicationDataContext : IdentityDbContext<ApplicationUser> { public ApplicationDataContext(DbContextOptions<ApplicationDataContext> options) : base(options) { } public DbSet<Student> Students { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<ApplicationUser>(b =>
{
b.HasMany(x => x.Claims).WithOne().HasForeignKey(x => x.UserId).IsRequired();
b.HasMany(x => x.Logins).WithOne().HasForeignKey(x => x.UserId).IsRequired();
b.HasMany(x => x.Tokens).WithOne().HasForeignKey(x => x.UserId).IsRequired();
b.HasMany(x => x.UserRoles).WithOne().HasForeignKey(x => x.UserId).IsRequired();
});
}
} //StartUp.cs中也要修改 services.AddDbContext<ApplicationDataContext>(options => { options.UseSqlServer(connectionString, b => b.MigrationsAssembly("NetCoreTestMVC2")); }); services.AddDefaultIdentity<ApplicationUser>(...).AddEntityFrameworkStores<ApplicationDataContext>();
注册策略:
#region 策略 [Authorize(Policy = "OnlyAdmin")] 等价 [Authorize(Roles = "Admin")] services.AddAuthorization(options => { options.AddPolicy("OnlyAdmin", policy => { policy.RequireRole(new string[] { "Admin" }); }); }); #endregion
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】