.net 6下創建identityserver4的項目過程記錄之【一】

首先聲明一下,我是按照下面的教程來進行操作的:

.NET 6 集成 IdentityServer4+AspNetCore Identity 讀取本地數據表用戶 - 董川民 (dongchuanmin.com)

具體步驟記錄如下:

 一、新建空白項目

  1、選擇Asp.net Core Api項目,如下圖

  

  2、輸入項目名稱,如下圖:

  

  3、選擇框架

  

 二、添加引用的類庫

   1、IdentityServer4

    

   2、IdentityServer4.AspNetIdentity

    

  3、Microsoft.EntityFrameworkCore

    選擇6.0.12版本

    

   4、Microsoft.AspNetCore.Identity.EntityFrameworkCore

    選擇6.0.12版本

    

   5、Microsoft.EntityFrameworkCore.Design

    選擇6.0.12版本

     

   6、Microsoft.EntityFrameworkCore.Tools

    

   7、Pomelo.EntityFrameworkCore.MySql

    

   8、NETCore.Encrypt【可以不用添加】

     

   下面是安裝需要的類庫後的總體列表:

  

 、新建類庫:IdpConfig.cs

  由於原作者沒有把api和client的配置放到數據庫裏,所以這裏是這樣配置的,代碼如下:

using IdentityServer4;
using IdentityServer4.Models;
namespace TestIdentityServer4InNetCore6
{
    public static class IdpConfig
    {
        public static IEnumerable<IdentityResource> GetIdentityResources()
        {
            return new IdentityResource[]
            {
            new IdentityResources.OpenId(),
            new IdentityResources.Profile(),
            new IdentityResources.Address(),
            new IdentityResources.Phone(),
            new IdentityResources.Email()
            };
        }
        public static IEnumerable<ApiResource> GetApiResources()
        {
            return new[]
            {
                new ApiResource("api1", "My API #1")
                {
                    Scopes = { "scope1"}
                }
            };
        }
        public static IEnumerable<Client> GetClients()
        {
            return new[]
            {
                new Client
                {
                    ClientId = "client",
                    AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                    ClientSecrets =
                    {
                        new Secret("secret".Sha256())
                    },
                    AllowedScopes = //允許當訪問的資源
                    {
                        "scope1",
                        IdentityServerConstants.StandardScopes.OpenId,
                        IdentityServerConstants.StandardScopes.Email,
                        IdentityServerConstants.StandardScopes.Address,
                        IdentityServerConstants.StandardScopes.Phone,
                        IdentityServerConstants.StandardScopes.Profile }
                }
            };
        }
        public static IEnumerable<ApiScope> GetScope()
        {
            return new ApiScope[] {
            new ApiScope("scope1"),
            new ApiScope("scope2"),
        };
        }
    }
}

 、新建類庫:ApplicationUser.cs

   此類庫繼承於IdentityUser,可以在上面擴展自己需要的用戶的字段,代碼如下:

using Microsoft.AspNetCore.Identity;
using System.ComponentModel;
namespace TestIdentityServer4InNetCore6
{
    public class ApplicationUser : IdentityUser
    {
        public string MySomething { get; set; } = "";
        /// <summary>
        /// 創建時間
        /// </summary>
        public DateTime CreateTime { get; set; }

        /// <summary>
        /// 創建人Id
        /// </summary>
        public string CreatorId { get; set; } = "";

        /// <summary>
        /// 否已刪除
        /// </summary>
        public bool Deleted { get; set; }


        /// <summary>
        /// 姓名
        /// </summary>
        public string RealName { get; set; }

        /// <summary>
        /// 性別
        /// </summary>
        public Sex Sex { get; set; }

        /// <summary>
        /// 出生日期
        /// </summary>
        public DateTime? Birthday { get; set; }

        /// <summary>
        /// 所屬部門Id
        /// </summary>
        public string DepartmentId { get; set; } = "";

        public string OtherData { get; set; } = "";

        // 用戶角色 用戶權限 用戶信息 用戶登錄tokens  重新綁定與父類的關係 命名必須和父類一致
        public virtual ICollection<IdentityUserRole<string>> UserRoles { 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 enum Sex
    {
        [Description("")]
        Man = 1,

        [Description("")]
        Woman = 0
    }
}

五、新建類庫:MyPasswordHasher.cs

  此類是處理密碼加密和判斷的,代碼如下:

using Microsoft.AspNetCore.Identity;
using NETCore.Encrypt.Extensions;
namespace TestIdentityServer4InNetCore6
{
    public class MyPasswordHasher : PasswordHasher<ApplicationUser>
    {
        public override string HashPassword(ApplicationUser user, string password)
        {
            //PasswordHasher<ApplicationUser> ph = new PasswordHasher<ApplicationUser>();
            //var pstr = ph.HashPassword(new ApplicationUser(), password);
            //return pstr;
            return password.MD5();
        }

        public override PasswordVerificationResult VerifyHashedPassword(ApplicationUser user, string hashedPassword, string providedPassword)
        {
            if (providedPassword.MD5().Equals(hashedPassword))
            {
                return PasswordVerificationResult.Success;
            }
            else
            {
                return PasswordVerificationResult.Failed;
            }
        }
    }
}

 六、新建類庫:IdpDbContext.cs

   此類庫爲數據庫的上下文,在裏面初始化了角色和用戶和種子數據,主要是便於測試用,代碼如下:

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace TestIdentityServer4InNetCore6
{
    public class IdpDbContext : IdentityDbContext<ApplicationUser>
    {
        public IdpDbContext(DbContextOptions<IdpDbContext> opt) : base(opt)
        {

        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
            builder.Entity<ApplicationUser>().ToTable("ApplicationUsers");
            MyPasswordHasher ph = new MyPasswordHasher();
            #region 初始化用戶與角色的種子數據
            //1. 更新用戶與角色的外鍵
            builder.Entity<ApplicationUser>(
                u => u.HasMany(x => x.UserRoles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired()
                );
            //2. 添加管理員角色
            var adminRoleId = "f8df1775-e889-46f4-acdd-421ec8d9ba64";
            builder.Entity<IdentityRole>().HasData(
                new IdentityRole()
                {
                    Id = adminRoleId,
                    Name = "Admin",
                    NormalizedName = "Admin".ToUpper()
                }
            );
            //3. 添加用戶
            var adminUserId = "f8df1775-e889-46f4-acdd-421ec8d9ba65";
            ApplicationUser adminUser = new ApplicationUser
            {
                Id = adminUserId,
                UserName = "admin",
                NormalizedUserName = "admin".ToUpper(),
                RealName = "admin",
                NormalizedEmail = "[email protected]".ToUpper(),
                Email = "[email protected]",
                TwoFactorEnabled = false,
                EmailConfirmed = true,
                PhoneNumber = "123456789",
                PhoneNumberConfirmed = false,

            };
            adminUser.PasswordHash = ph.HashPassword(adminUser, "123456");
            builder.Entity<ApplicationUser>().HasData(adminUser);
            //4. 給用戶加入管理員角色
            builder.Entity<IdentityUserRole<string>>().HasData(
                new IdentityUserRole<string>()
                {
                    RoleId = adminRoleId,
                    UserId = adminUserId
                }
                );
            #endregion

        }
    }
}

 七、新建類庫:MyUserManager.cs

  繼承於UserManager

using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
namespace TestIdentityServer4InNetCore6
{
    public class MyUserManager : UserManager<ApplicationUser>
    {
        public MyUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher,
          IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger)
           : base(store, optionsAccessor, new MyPasswordHasher(), userValidators, passwordValidators, keyNormalizer, errors, services, logger)
        {
            optionsAccessor.Value.Password.RequireDigit = false;
            optionsAccessor.Value.Password.RequiredLength = 4;
            optionsAccessor.Value.Password.RequireLowercase = false;
            optionsAccessor.Value.Password.RequireUppercase = false;
            optionsAccessor.Value.Password.RequireNonAlphanumeric = false;
        }

    }
}

 

八、修改Program.cs類

  主要是配置數據庫和identityserver4,數據庫連接字符串記得換成自己的,代碼如下:

using IdentityModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using System.Security.Claims;
using TestIdentityServer4InNetCore6;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContext<IdpDbContext>(opt =>
{
    opt.UseMySql("server=127.0.0.1;Port=3306;database=testidentityserver;uid=root;pwd=123456;", new MySqlServerVersion(new Version(8, 0, 29)));
});

builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
                .AddUserManager<MyUserManager>()
                .AddEntityFrameworkStores<IdpDbContext>()
                .AddDefaultTokenProviders();

builder.Services.AddIdentityServer()
    .AddDeveloperSigningCredential()

    .AddInMemoryIdentityResources(IdpConfig.GetIdentityResources())
    .AddInMemoryClients(IdpConfig.GetClients())
    .AddInMemoryApiScopes(IdpConfig.GetScope())
    .AddInMemoryApiResources(IdpConfig.GetApiResources())
    //.AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>() //這句可以打開自主驗證登錄用戶
    //.AddProfileService<MyProfileService>()
    .AddAspNetIdentity<ApplicationUser>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseIdentityServer();

app.UseAuthorization();

app.MapControllers();

app.Run();

九、新建mysql空數據庫

  數據庫的名稱爲:testidentityserver【跟第八步裏填寫的數據庫名稱要保持一致】

十、執行數據遷移

  1、打開“程序包管理器控制檯”,輸入“Add-Migration CreateIdentitySchema”命令,代碼和截圖如下:

Add-Migration CreateIdentitySchema

  

 

   2、恢復數據庫,輸入“Update-Database”,如下圖:

Update-Database

  

 

   3、執行上一步的命令後,數據庫裏會自動創建如下表:

  

 

 十、使用postman測試

  1、啓動當前api項目,啓動成功後,界面如下:

  

 

   2、使用postman調試

  按照下圖的填寫參數,出現如下界面,表示運行成功

  

 

 

  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章