.Net6集成IdentityServer4?+AspNetCore?Identity讀取數(shù)據(jù)表用戶(hù)且鑒權(quán)授權(quán)管理API
前言
IdentityServer4 實(shí)現(xiàn)鑒權(quán)、授權(quán),AspNetCore Identity實(shí)現(xiàn)數(shù)據(jù)庫(kù)用戶(hù)管理表直接生成。
ps:IdentityServer4文檔上最后給的例子是 // 配置使用內(nèi)存存儲(chǔ)用戶(hù)信息,但使用 EF 存儲(chǔ)客戶(hù)端和資源信息,
我初步要實(shí)現(xiàn)的是 //數(shù)據(jù)庫(kù)存儲(chǔ)用戶(hù)信息 內(nèi)存存儲(chǔ)資源 (下一步資源也放數(shù)據(jù)庫(kù) 以后弄好了有機(jī)會(huì)更)
1.創(chuàng)建.Net6 API程序
一頓引用,包括
防止圖片掛掉打一遍文字:
- IdentityServer4、
- IdengtityServer4.AspNetIdentity、
- AspNetCore.Identity.EntityFrameWorkCore(生成數(shù)據(jù)庫(kù)表用的)、
- EntityFrameWork+Disign+Tool三件套 (缺了不能自動(dòng)遷移)、
- Pomelo.EntityFrameWorkCore.MySql(我是用的MySql,如果是SqlServer 不用這個(gè)用一個(gè)大概叫EF.Sqlserver的)、
- Encrypt (加密MD5用的 不必須)、
下面那個(gè)是自帶的。
2.建立數(shù)據(jù)庫(kù)連接類(lèi)
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using MyIDP; using MyIDP.Models; using MyIDP.Permission; 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=AccountDb;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(MyIDP.IdpConfig.GetIdentityResources()) .AddInMemoryClients(MyIDP.IdpConfig.GetClients()) .AddInMemoryApiScopes( MyIDP.IdpConfig.GetScope()) .AddInMemoryApiResources( MyIDP.IdpConfig.GetApiResources()) //.AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>() //這句可以打開(kāi)自主驗(yàn)證登錄用戶(hù) //.AddProfileService<MyProfileService>() .AddAspNetIdentity<ApplicationUser>() //.AddTestUsers(new List<IdentityServer4.Test.TestUser> //{ // new IdentityServer4.Test.TestUser // { // SubjectId="123", // Username = "alice", // Password = "alice", // Claims = new List<Claim>() { // new Claim(JwtClaimTypes.Role, "superadmin"), // new Claim(JwtClaimTypes.Role, "admin") // } // } //}) ; 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();
3.Program里開(kāi)始加?xùn)|西(如果是歷史的Net版本,是在StartUp里)
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using MyIDP; using MyIDP.Models; using MyIDP.Permission; 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=AccountDb;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(MyIDP.IdpConfig.GetIdentityResources()) .AddInMemoryClients(MyIDP.IdpConfig.GetClients()) .AddInMemoryApiScopes( MyIDP.IdpConfig.GetScope()) .AddInMemoryApiResources( MyIDP.IdpConfig.GetApiResources()) //.AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>() //這句可以打開(kāi)自主驗(yàn)證登錄用戶(hù) //.AddProfileService<MyProfileService>() .AddAspNetIdentity<ApplicationUser>() //.AddTestUsers(new List<IdentityServer4.Test.TestUser> //{ // new IdentityServer4.Test.TestUser // { // SubjectId="123", // Username = "alice", // Password = "alice", // Claims = new List<Claim>() { // new Claim(JwtClaimTypes.Role, "superadmin"), // new Claim(JwtClaimTypes.Role, "admin") // } // } //}) ; 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();
因?yàn)槭褂玫氖莾?nèi)存儲(chǔ)存t鑒權(quán)信息的方式,所以建立IdentityServer4的配置類(lèi)IdpConfig
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 ApiResource[] //{ // new ApiResource("api1", "My API #1",new List<string>(){JwtClaimTypes.Role}) //}; //新寫(xiě)法 return new[] { new ApiResource("api1", "My API #1") { Scopes = { "scope1"} } }; } public static IEnumerable<Client> GetClients() { return new[] { #region MyRegion //// client credentials flow client //new Client //{ // ClientId = "console client", // ClientName = "Client Credentials Client", // AllowedGrantTypes = GrantTypes.ClientCredentials, // ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) }, // AllowedScopes = { "api1" } //}, #endregion // wpf client, password grant new Client { ClientId = "client", AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = //允許當(dāng)訪(fǎng)問(wèn)的資源 { "scope1", //"api1", 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"), }; } }
數(shù)據(jù)庫(kù)的usernamager
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; } }
重寫(xiě)驗(yàn)證密碼的方法類(lèi)MyResourceOwnerPasswordValidator,(如果沒(méi)有打開(kāi)Program中的AddResourceOwnerValidator<MyResourceOwnerPasswordValidator>() 則不需要)
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, "驗(yàn)證被拒絕,用戶(hù)名或者密碼為空。"); return; } var user = await userManager.FindByNameAsync(context.UserName); if (user == null) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "驗(yàn)證失敗,不存在當(dāng)前用戶(hù)。"); return; } //檢驗(yàn)用戶(hù)密碼(雖然我也不知道他的密碼是采用什么加密方式得到的,但是我也不需要知道) var passwordPass = await userManager.CheckPasswordAsync(user, context.Password); if (!passwordPass) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "驗(yàn)證失敗,用戶(hù)憑證錯(cuò)誤"); 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; } }
MyPasswordHasher
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; } } }
創(chuàng)建自己的User類(lèi) ApplicationUser繼承 IdentityUser 復(fù)寫(xiě)自帶的AspNetUser表
public class ApplicationUser : IdentityUser { public string MySomething { get; set; } = ""; /// <summary> /// 創(chuàng)建時(shí)間 /// </summary> public DateTime CreateTime { get; set; } /// <summary> /// 創(chuàng)建人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> /// 所屬部門(mén)Id /// </summary> public string DepartmentId { get; set; } = ""; public string OtherData { get; set; } = ""; // 用戶(hù)角色 用戶(hù)權(quán)限 用戶(hù)信息 用戶(hù)登錄tokens 重新綁定與父類(lèi)的關(guān)系 命名必須和父類(lèi)一致 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 }
至此可以生成數(shù)據(jù)庫(kù)遷移后 Postman測(cè)試一下:
到此這篇關(guān)于.Net6集成IdentityServer4 +AspNetCore Identity讀取數(shù)據(jù)表用戶(hù)且鑒權(quán)授權(quán)管理API的文章就介紹到這了,更多相關(guān).Net6 讀取數(shù)據(jù)表用戶(hù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.net 運(yùn)用二進(jìn)制位運(yùn)算進(jìn)行數(shù)據(jù)庫(kù)權(quán)限管理
.net 運(yùn)用二進(jìn)制位運(yùn)算進(jìn)行數(shù)據(jù)庫(kù)權(quán)限管理 ,需要的朋友可以參考一下2013-02-02Javascript調(diào)用Webservice的多種方法
通過(guò)xmlhttp+webservice(原始方法)2009-02-02.net通過(guò)Action進(jìn)行Options參數(shù)的傳遞的方法
在.NET Core中,使用Action和Options參數(shù)方式配置服務(wù)并將配置信息對(duì)象注冊(cè)到IServiceCollection的好處在于,它提供了更高級(jí)別的可配置性和可擴(kuò)展性,這篇文章主要介紹了.net通過(guò)Action進(jìn)行Options參數(shù)的傳遞,你知道是怎么實(shí)現(xiàn)的嗎,需要的朋友可以參考下2023-12-12asp.net上傳文件到數(shù)據(jù)庫(kù)的解決方案
這篇文章主要介紹了ASP.NET上傳文件到數(shù)據(jù)庫(kù),先從文字上了解一下上傳文件到數(shù)據(jù)庫(kù)的具體步驟,再?gòu)拇a上來(lái)實(shí)現(xiàn),需要的朋友可以參考下2015-09-09Asp.Mvc 2.0實(shí)現(xiàn)用戶(hù)登錄與注銷(xiāo)功能實(shí)例講解(2)
這篇文章主要介紹了Asp.Mvc 2.0實(shí)現(xiàn)用戶(hù)登錄與注銷(xiāo)功能,用戶(hù)登錄方式都是FORM表單驗(yàn)證方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-08-08ASP.NET中實(shí)現(xiàn)jQuery Validation-Engine的Ajax驗(yàn)證實(shí)現(xiàn)代碼
在jQuery的表變驗(yàn)證插件中Validation-Engine是一款高質(zhì)量的產(chǎn)品,提示效果非常精美,而且里面包含了AJAX驗(yàn)證功能2012-05-05Entity?Framework管理一對(duì)一實(shí)體關(guān)系
本文詳細(xì)講解了Entity?Framework管理一對(duì)一實(shí)體關(guān)系的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03.NET數(shù)組使用中的注意事項(xiàng)小結(jié)
這篇文章主要介紹了.NET數(shù)組使用中的注意事項(xiàng),總結(jié)了常見(jiàn)的三個(gè)數(shù)組使用中的注意事項(xiàng),對(duì)于.NET初學(xué)者有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12