IdentityServer4(六):集成ASP.NET Core Identity
程序员文章站
2024-03-13 12:40:09
...
此前我们已经使用EFCore将IdentityServer4相关配置写入SqlServer,但是用户数据还是写死的TestUser,本篇将集成
ASP.NET Core Identity
,将用户数据保存到SqlServer中,当然,您也可以使用自建的用户数据库。
开始前先安装必要的nuget包
Install-Package Microsoft.AspNetCore.Identity.EntityFrameworkCore -Version 3.1.1
Install-Package Microsoft.EntityFrameworkCore.SqlServer -Version 3.1.1
添加上下文
public class AspNetAccountDbContext : IdentityDbContext<ApplicationUser>
{
public AspNetAccountDbContext(DbContextOptions<AspNetAccountDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
向容器中添加服务
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AspNetAccountDbContext>(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("DefaultAspNetAccountConnection"));
});
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AspNetAccountDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
// 密码复杂度配置
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
});
// 为了代码简单一点,后面的配置省略,可参考前文
}
登录控制器的修改
删除原先的TestUserStore,使用ASP.NET Core Identity进行操作
public class AccountController : Controller
{
private UserManager<ApplicationUser> _userManager;
private SignInManager<ApplicationUser> _signInManager;
private IIdentityServerInteractionService _interaction;
public AccountController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, IIdentityServerInteractionService interaction)
{
_userManager = userManager;
_signInManager = signInManager;
_interaction = interaction;
}
public IActionResult Login(string returnUrl)
{
ViewData["ReturnUrl"] = returnUrl;
return View();
}
[HttpPost]
public async Task<IActionResult> Login(LoginViewModel loginViewModel, string returnUrl)
{
if (!ModelState.IsValid)
{
return View();
}
var user = await _userManager.FindByEmailAsync(loginViewModel.Email);
if (user == null)
{
ModelState.AddModelError(nameof(loginViewModel.Email), $"Email {loginViewModel.Email} not exists");
}
else
{
if (await _userManager.CheckPasswordAsync(user, loginViewModel.Password))
{
AuthenticationProperties props = null;
if (loginViewModel.RememberMe)
{
props = new AuthenticationProperties
{
IsPersistent = true,
ExpiresUtc = DateTimeOffset.UtcNow.Add(TimeSpan.FromMinutes(30))
};
}
await _signInManager.SignInAsync(user, props);
if (_interaction.IsValidReturnUrl(returnUrl))
{
return Redirect(returnUrl);
}
return Redirect("~/");
}
ModelState.AddModelError(nameof(loginViewModel.Password), "Wrong password");
}
return View(loginViewModel);
}
}
数据迁移
执行命令
add-migration InitialAspNetAccountDbMigration -c AspNetAccountDbContext -o Data/Migrations/Application/AspNetAccountDb
可以看到成功添加了迁移代码
执行命令生成数据库
update-database -c AspNetAccountDbContext
成功生成
播种默认用户数据
public class SeedData
{
public static void EnsureSeedAspNetAccountData(string connectionString)
{
var services = new ServiceCollection();
services.AddLogging();
services.AddDbContext<AspNetAccountDbContext>(options =>
{
options.UseSqlServer(connectionString);
});
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<AspNetAccountDbContext>()
.AddDefaultTokenProviders();
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = true;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
options.Password.RequireLowercase = false;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
});
using (var serviceProvider = services.BuildServiceProvider())
{
using (var scope = serviceProvider.GetRequiredService<IServiceScopeFactory>().CreateScope())
{
var context = scope.ServiceProvider.GetService<AspNetAccountDbContext>();
context.Database.Migrate();
var userManager = scope.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var zhangsan = userManager.FindByNameAsync("zhangsan").Result;
if (zhangsan == null)
{
zhangsan = new ApplicationUser
{
UserName = "zhangsan",
Email = "aaa@qq.com"
};
var result = userManager.CreateAsync(zhangsan, "123456").Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
result = userManager.AddClaimsAsync(zhangsan, new Claim[] {
new Claim(JwtClaimTypes.Name, "张三"),
new Claim(JwtClaimTypes.GivenName, "三"),
new Claim(JwtClaimTypes.FamilyName, "张"),
new Claim(JwtClaimTypes.Email, "aaa@qq.com"),
new Claim(JwtClaimTypes.EmailVerified, "true", ClaimValueTypes.Boolean),
new Claim(JwtClaimTypes.WebSite, "http://zhangsan.com"),
new Claim(JwtClaimTypes.Address, @"{ '城市': '杭州', '邮政编码': '310000' }",
IdentityServer4.IdentityServerConstants.ClaimValueTypes.Json)
}).Result;
if (!result.Succeeded)
{
throw new Exception(result.Errors.First().Description);
}
}
// 为了代码简单一点,删除其他用户数据
}
}
}
}
当我们成功运行程序后,查看数据库,可以看到种子数据已经插入
更多
可访问GitHub查看源码
上一篇: C语言链表实现工资管理系统
推荐阅读
-
IdentityServer4(六):集成ASP.NET Core Identity
-
ASP.NET Core Identity 实战(3)认证过程
-
【译】ASP.NET Identity Core 从零开始
-
ASP.NET Core 之 Identity 入门(二)
-
【asp.net core 系列】15 自定义Identity
-
ASP.NET Core 之 Identity 入门(三)
-
ASP.NET Core 之 Identity 入门(一)
-
从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用
-
.netcore入门32:asp.net core集成NLog
-
学习ASP.NET Core Razor 编程系列六——数据库初始化