欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IdentityServer4(六):集成ASP.NET Core Identity

程序员文章站 2024-03-13 12:40:09
...


此前我们已经使用EFCoreIdentityServer4相关配置写入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

可以看到成功添加了迁移代码
IdentityServer4(六):集成ASP.NET Core Identity
执行命令生成数据库

update-database -c AspNetAccountDbContext

成功生成
IdentityServer4(六):集成ASP.NET Core Identity

播种默认用户数据

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);
                    }
                }
                // 为了代码简单一点,删除其他用户数据
            }
        }
    }
}

当我们成功运行程序后,查看数据库,可以看到种子数据已经插入
IdentityServer4(六):集成ASP.NET Core Identity

更多

可访问GitHub查看源码

相关标签: IdentityServer4