.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

  • .Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API已关闭评论
  • 180 次浏览
  • A+
所属分类:.NET技术
摘要

IdentityServer4 实现鉴权、授权,AspNetCore Identity实现数据库用户管理表直接生成。

IdentityServer4 实现鉴权、授权,AspNetCore Identity实现数据库用户管理表直接生成。

ps:IdentityServer4文档上最后给的例子是 // 配置使用内存存储用户信息,但使用 EF 存储客户端和资源信息,

  我初步要实现的是 //数据库存储用户信息   内存存储资源   (下一步资源也放数据库  以后弄好了有机会更)

直接干活:

1.创建.Net6 API程序,一顿引用,包括

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

防止图片挂掉打一遍文字:

IdentityServer4、

IdengtityServer4.AspNetIdentity、

AspNetCore.Identity.EntityFrameWorkCore(生成数据库表用的)、

EntityFrameWork+Disign+Tool三件套 (缺了不能自动迁移)、

Pomelo.EntityFrameWorkCore.MySql(我是用的MySql,如果是SqlServer 不用这个用一个大概叫EF.Sqlserver的)、

Encrypt (加密MD5用的 不必须)、

下面那个是自带的。

2.建立数据库连接类

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

 1  public class IdpDbContext : IdentityDbContext<ApplicationUser>  2     {  3         public IdpDbContext(DbContextOptions<IdpDbContext> opt) : base(opt)  4         {  5   6         }  7         protected override void OnModelCreating(ModelBuilder builder)  8         {  9             base.OnModelCreating(builder); 10             builder.Entity<ApplicationUser>().ToTable("ApplicationUsers"); 11             #region # 12             //builder.Entity<IdentityUserLogin<string>>().ToTable("ApplicationLogins"); 13             //builder.Entity<IdentityUserClaim<string>>().ToTable("ApplicationUserClaims"); 14             //builder.Entity<ApplicationUserRole>().ToTable("ApplicationUserRoles"); 15             //builder.Entity<IdentityUserToken<string>>().ToTable("ApplicationUserTokens"); 16             //builder.Entity<ApplicationRole>().ToTable("ApplicationRoles"); 17             //builder.Entity<IdentityRoleClaim<string>>().ToTable("ApplicationRoleClaims"); 18             //builder.Entity<ApplicationUserRole>().HasKey(t => t.Id).HasName("PK_UserRole_ID_KEY"); 19             #endregion 20  21             builder.Entity<ApplicationUser>().HasData( 22                 new ApplicationUser() 23                 { 24                     Id = Guid.NewGuid().ToString(), 25                     RealName = "alice1", 26                     UserName = "alice1", 27                     PasswordHash = "alice1" 28                 }); 29             #region 初始化用戶与角色的种子数据 30             //1. 更新用戶与角色的外鍵 31             builder.Entity<ApplicationUser>( 32                 u => u.HasMany(x => x.UserRoles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired() 33                 ); 34             //2. 添加管理员角色 35             var adminRoleId = "f8df1775-e889-46f4-acdd-421ec8d9ba64"; 36             builder.Entity<IdentityRole>().HasData( 37                 new IdentityRole() 38                 { 39                     Id = adminRoleId, 40                     Name = "Admin", 41                     NormalizedName = "Admin".ToUpper() 42                 } 43             ); 44             //3. 添加用户 45             var adminUserId = "f8df1775-e889-46f4-acdd-421ec8d9ba65"; 46             ApplicationUser adminUser = new ApplicationUser 47             { 48                 Id = adminUserId, 49                 UserName = "admin", 50                 NormalizedUserName= "admin".ToUpper(), 51                 RealName = "admin", 52                 NormalizedEmail = "admin@qq.com".ToUpper(), 53                 Email = "admin@qq.com", 54                 TwoFactorEnabled = false, 55                 EmailConfirmed = true, 56                 PhoneNumber = "123456789", 57                 PhoneNumberConfirmed = false, 58  59             }; 60             MyPasswordHasher ph = new MyPasswordHasher(); 61             adminUser.PasswordHash = ph.HashPassword(adminUser, "123456"); 62             builder.Entity<ApplicationUser>().HasData(adminUser); 63             //4. 给用户加入管理员角色 64             builder.Entity<IdentityUserRole<string>>().HasData( 65                 new IdentityUserRole<string>() 66                 { 67                     RoleId = adminRoleId, 68                     UserId = adminUserId 69                 } 70                 ); 71             #endregion 72  73         } 74     }

View Code

 

3.Program里开始加东西(如果是历史的Net版本,是在StartUp里):

直接代码

 1 using Microsoft.AspNetCore.Identity;  2 using Microsoft.EntityFrameworkCore;  3 using MyIDP;  4 using MyIDP.Models;  5 using MyIDP.Permission;  6   7 var builder = WebApplication.CreateBuilder(args);  8   9 // Add services to the container. 10 builder.Services.AddControllers(); 11 // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle 12 builder.Services.AddEndpointsApiExplorer(); 13 builder.Services.AddSwaggerGen(); 14  15 //由此重要 16 builder.Services.AddDbContext<IdpDbContext>(opt => 17 { 18     opt.UseMySql("server=127.0.0.1;Port=3306;database=AccountDb;uid=root;pwd=123456;", new MySqlServerVersion(new Version(8,0,29))); 19 }); 20  21 builder.Services.AddIdentity<ApplicationUser, IdentityRole>() 22                 .AddUserManager<MyUserManager>() 23                 .AddEntityFrameworkStores<IdpDbContext>() 24                 .AddDefaultTokenProviders(); 25  26 builder.Services.AddIdentityServer() 27     .AddDeveloperSigningCredential() 28  29     .AddInMemoryIdentityResources(MyIDP.IdpConfig.GetIdentityResources()) 30     .AddInMemoryClients(MyIDP.IdpConfig.GetClients()) 31     .AddInMemoryApiScopes( MyIDP.IdpConfig.GetScope()) 32     .AddInMemoryApiResources( MyIDP.IdpConfig.GetApiResources())    //.AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>() //这句可以打开自主验证登录用户 33     //.AddProfileService<MyProfileService>() 34     .AddAspNetIdentity<ApplicationUser>() 35     //.AddTestUsers(new List<IdentityServer4.Test.TestUser> 36     //{ 37     //    new IdentityServer4.Test.TestUser 38     //    { 39     //        SubjectId="123", 40     //        Username = "alice", 41     //        Password = "alice", 42     //        Claims = new List<Claim>() { 43     //            new Claim(JwtClaimTypes.Role, "superadmin"), 44     //            new Claim(JwtClaimTypes.Role, "admin") 45     //        } 46     //    } 47     //}) 48     ; 49  50 var app = builder.Build(); 51  52 // Configure the HTTP request pipeline. 53 if (app.Environment.IsDevelopment()) 54 { 55     app.UseSwagger(); 56     app.UseSwaggerUI(); 57 } 58  59 app.UseIdentityServer(); 60 app.UseAuthorization(); 61 app.MapControllers(); 62 app.Run();

因为使用的是内存储存t鉴权信息的方式,所以建立IdentityServer4的配置类IdpConfig

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

 1  public static class IdpConfig  2     {  3         public static IEnumerable<IdentityResource> GetIdentityResources()  4         {  5             return new IdentityResource[]  6             {  7                 new IdentityResources.OpenId(),  8                 new IdentityResources.Profile(),  9                 new IdentityResources.Address(), 10                 new IdentityResources.Phone(), 11                 new IdentityResources.Email() 12             }; 13         } 14  15         public static IEnumerable<ApiResource> GetApiResources() 16         { 17             //return new ApiResource[] 18             //{ 19             //    new ApiResource("api1", "My API #1",new List<string>(){JwtClaimTypes.Role}) 20             //}; 21             //新写法 22             return new[] 23             { 24                 new ApiResource("api1", "My API #1") 25                 { 26                     Scopes = { "scope1"} 27                 } 28             }; 29         } 30  31         public static IEnumerable<Client> GetClients() 32         { 33             return new[] 34             { 35                 #region MyRegion 36                  //// client credentials flow client 37                 //new Client 38                 //{ 39                 //    ClientId = "console client", 40                 //    ClientName = "Client Credentials Client", 41  42                 //    AllowedGrantTypes = GrantTypes.ClientCredentials, 43  44                 //    ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) }, 45  46                 //    AllowedScopes = { "api1" } 47                 //}, 48  49     #endregion 50                 51                 // wpf client, password grant 52                 new Client 53                 { 54                     ClientId = "client", 55                     AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, 56                     ClientSecrets = 57                     { 58                         new Secret("secret".Sha256()) 59                     }, 60                     AllowedScopes = //允许当访问的资源 61                     { 62                         "scope1", 63                         //"api1", 64                         IdentityServerConstants.StandardScopes.OpenId, 65                         IdentityServerConstants.StandardScopes.Email, 66                         IdentityServerConstants.StandardScopes.Address, 67                         IdentityServerConstants.StandardScopes.Phone, 68                         IdentityServerConstants.StandardScopes.Profile } 69                 } 70             }; 71         } 72  73         public static IEnumerable<ApiScope> GetScope() 74         { 75             return new ApiScope[] { 76                 new ApiScope("scope1"), 77                 new ApiScope("scope2"), 78             }; 79         } 80     }

View Code

数据库的usernamager

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

 1 public class MyUserManager : UserManager<ApplicationUser>  2     {  3         public MyUserManager(IUserStore<ApplicationUser> store, IOptions<IdentityOptions> optionsAccessor, IPasswordHasher<ApplicationUser> passwordHasher,  4           IEnumerable<IUserValidator<ApplicationUser>> userValidators, IEnumerable<IPasswordValidator<ApplicationUser>> passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<ApplicationUser>> logger)  5            : base(store, optionsAccessor, new MyPasswordHasher(), userValidators, passwordValidators, keyNormalizer, errors, services, logger)  6         {  7             optionsAccessor.Value.Password.RequireDigit = false;  8             optionsAccessor.Value.Password.RequiredLength = 4;  9             optionsAccessor.Value.Password.RequireLowercase = false; 10             optionsAccessor.Value.Password.RequireUppercase = false; 11             optionsAccessor.Value.Password.RequireNonAlphanumeric = false; 12         } 13  14     }

View Code

重写验证密码的方法类MyResourceOwnerPasswordValidator,(如果没有打开Program中的AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>() 则不需要)

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

public class MyResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator     {         public readonly SignInManager<ApplicationUser> signInManager;         private readonly MyUserManager userManager;         //public readonly IEventService service;         public MyResourceOwnerPasswordValidator(MyUserManager userService, SignInManager<ApplicationUser> signInManager)//, IEventService service)         {             userManager = userService;             this.signInManager = signInManager;             //this.service = service;          }         public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)         {             if (string.IsNullOrEmpty(context.UserName) || string.IsNullOrEmpty(context.Password))             {                 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "验证被拒绝,用户名或者密码为空。");                 return;             }             var user = await userManager.FindByNameAsync(context.UserName);             if (user == null)             {                 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "验证失败,不存在当前用户。");                 return;             }             //检验用户密码(虽然我也不知道他的密码是采用什么加密方式得到的,但是我也不需要知道)              var passwordPass = await userManager.CheckPasswordAsync(user, context.Password);             if (!passwordPass)             {                 context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "验证失败,用户凭证错误");                 return;             }             else             {                 try                 {                     await userManager.AddLoginAsync(user, new UserLoginInfo(user.Id, "", user.UserName));                 }                 catch (Exception ex)                 {                     ;                 }                 finally                 {                     context.Result = new GrantValidationResult(user.Id, GrantType.ResourceOwnerPassword, new List<Claim>() { new Claim("account", user.UserName) });                  }             }             return;         }      }

View Code

MyPasswordHasher

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

 1 public class MyPasswordHasher : PasswordHasher<ApplicationUser>  2     {  3         public override string HashPassword(ApplicationUser user, string password)  4         {  5             //PasswordHasher<ApplicationUser> ph = new PasswordHasher<ApplicationUser>();  6             //var pstr = ph.HashPassword(new ApplicationUser(), password);  7             //return pstr;  8             return password.MD5();  9         } 10  11         public override PasswordVerificationResult VerifyHashedPassword(ApplicationUser user, string hashedPassword, string providedPassword) 12         { 13             if (providedPassword.MD5().Equals(hashedPassword)) 14             { 15                 return PasswordVerificationResult.Success; 16             } 17             else 18             { 19                 return PasswordVerificationResult.Failed; 20             } 21         } 22     }

View Code

创建自己的User类 ApplicationUser继承 IdentityUser  复写自带的AspNetUser表

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API

  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     }

View Code

至此可以生成数据库迁移后 Postman测试一下

.Net6集成IdentityServer4 +AspNetCore Identity读取本地数据表用户 独立鉴权授权管理API