.Net6集成IdentityServer4?+AspNetCore?Identity讀取數(shù)據(jù)表用戶且鑒權(quán)授權(quán)管理API
前言
IdentityServer4 實現(xiàn)鑒權(quán)、授權(quán),AspNetCore Identity實現(xiàn)數(shù)據(jù)庫用戶管理表直接生成。
ps:IdentityServer4文檔上最后給的例子是 // 配置使用內(nèi)存存儲用戶信息,但使用 EF 存儲客戶端和資源信息,
我初步要實現(xiàn)的是 //數(shù)據(jù)庫存儲用戶信息 內(nèi)存存儲資源 (下一步資源也放數(shù)據(jù)庫 以后弄好了有機會更)
1.創(chuàng)建.Net6 API程序
一頓引用,包括

防止圖片掛掉打一遍文字:
- IdentityServer4、
- IdengtityServer4.AspNetIdentity、
- AspNetCore.Identity.EntityFrameWorkCore(生成數(shù)據(jù)庫表用的)、
- EntityFrameWork+Disign+Tool三件套 (缺了不能自動遷移)、
- Pomelo.EntityFrameWorkCore.MySql(我是用的MySql,如果是SqlServer 不用這個用一個大概叫EF.Sqlserver的)、
- Encrypt (加密MD5用的 不必須)、
下面那個是自帶的。
2.建立數(shù)據(jù)庫連接類
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>() //這句可以打開自主驗證登錄用戶
//.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里開始加?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>() //這句可以打開自主驗證登錄用戶
//.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();因為使用的是內(nèi)存儲存t鑒權(quán)信息的方式,所以建立IdentityServer4的配置類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})
//};
//新寫法
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)訪問的資源
{
"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ù)庫的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;
}
}重寫驗證密碼的方法類MyResourceOwnerPasswordValidator,(如果沒有打開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, "驗證被拒絕,用戶名或者密碼為空。");
return;
}
var user = await userManager.FindByNameAsync(context.UserName);
if (user == null)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "驗證失敗,不存在當(dāng)前用戶。");
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;
}
}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類 ApplicationUser繼承 IdentityUser 復(fù)寫自帶的AspNetUser表
public class ApplicationUser : IdentityUser
{
public string MySomething { get; set; } = "";
/// <summary>
/// 創(chuàng)建時間
/// </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>
/// 所屬部門Id
/// </summary>
public string DepartmentId { get; set; } = "";
public string OtherData { get; set; } = "";
// 用戶角色 用戶權(quán)限 用戶信息 用戶登錄tokens 重新綁定與父類的關(guān)系 命名必須和父類一致
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ù)庫遷移后 Postman測試一下:

到此這篇關(guān)于.Net6集成IdentityServer4 +AspNetCore Identity讀取數(shù)據(jù)表用戶且鑒權(quán)授權(quán)管理API的文章就介紹到這了,更多相關(guān).Net6 讀取數(shù)據(jù)表用戶內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
.net 運用二進制位運算進行數(shù)據(jù)庫權(quán)限管理
.net 運用二進制位運算進行數(shù)據(jù)庫權(quán)限管理 ,需要的朋友可以參考一下2013-02-02
Javascript調(diào)用Webservice的多種方法
通過xmlhttp+webservice(原始方法)2009-02-02
.net通過Action進行Options參數(shù)的傳遞的方法
在.NET Core中,使用Action和Options參數(shù)方式配置服務(wù)并將配置信息對象注冊到IServiceCollection的好處在于,它提供了更高級別的可配置性和可擴展性,這篇文章主要介紹了.net通過Action進行Options參數(shù)的傳遞,你知道是怎么實現(xiàn)的嗎,需要的朋友可以參考下2023-12-12
Asp.Mvc 2.0實現(xiàn)用戶登錄與注銷功能實例講解(2)
這篇文章主要介紹了Asp.Mvc 2.0實現(xiàn)用戶登錄與注銷功能,用戶登錄方式都是FORM表單驗證方式,具有一定的參考價值,感興趣的小伙伴們可以參考一下2015-08-08
ASP.NET中實現(xiàn)jQuery Validation-Engine的Ajax驗證實現(xiàn)代碼
在jQuery的表變驗證插件中Validation-Engine是一款高質(zhì)量的產(chǎn)品,提示效果非常精美,而且里面包含了AJAX驗證功能2012-05-05
Entity?Framework管理一對一實體關(guān)系
本文詳細講解了Entity?Framework管理一對一實體關(guān)系的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03

