IdentityServer4提供的demo 是用的自己的表結構,但是對於我們來說就不是很適用了,研究了下他的源碼發現他的密碼模式,大概就是更改下面幾個方法大,致就是讀取數據庫數據,與context.username ,password,進行比對,一致則通過,不一致就是失敗
public class ProfileService : IProfileService {
//services
private IUserRepository _userRepository = new UserRepository();
//build claims array from user data
public static Claim[] GetUserClaims(User user)
{
var c = new Claim[] { };
c[0] = new Claim("user_id", "465464");
c[1] = new Claim("sub", "465464");
return c;
}
/// <summary>
/// 每當請求有關用戶的聲明時(例如,在令牌創建期間或通過userinfo端點),都會調用此方法
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{
try
{
//depending on the scope accessing the user data.
if (!string.IsNullOrEmpty(context.Subject.Identity.Name))
{
//get user from db (in my case this is by email)
var user = await _userRepository.FindAsync(45121);
if (user != null)
{
var claims = GetUserClaims(user);
//set issued claims to return
context.IssuedClaims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();
}
}
else
{
//get subject from context (this was set ResourceOwnerPasswordValidator.ValidateAsync),
//where and subject was set to my user id.
var userId = context.Subject.Claims.FirstOrDefault(x => x.Type == "sub");
if (!string.IsNullOrEmpty(userId?.Value) && long.Parse(userId.Value) > 0)
{
//get user from db (find user by user id)
var user = await _userRepository.FindAsync(long.Parse(userId.Value));
// issue the claims for the user
if (user != null)
{
var claims = ResourceOwnerPasswordValidator.GetUserClaims(user);
context.IssuedClaims = claims.Where(x => context.RequestedClaimTypes.Contains(x.Type)).ToList();
}
}
}
}
catch (Exception ex)
{
//log your error
}
}
//check if user account is active.
public async Task IsActiveAsync(IsActiveContext context)
{
try
{
//get subject from context (set in ResourceOwnerPasswordValidator.ValidateAsync),
var userId = context.Subject.Claims.FirstOrDefault(x => x.Type == "user_id");
if (!string.IsNullOrEmpty(userId?.Value) && long.Parse(userId.Value) > 0)
{
var user = await _userRepository.FindAsync(long.Parse(userId.Value));
if (user != null)
{
if (user.IsActive)
{
context.IsActive = user.IsActive;
}
}
}
}
catch (Exception ex)
{
//handle error logging
}
}
}
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator {
private IUserRepository _userRepository = new UserRepository();
//build claims array from user data
//build claims array from user data
public static Claim[] GetUserClaims(User user)
{
var c = new Claim[] { };
c[0] = new Claim("user_id", "465464");
c[1] = new Claim("sub", "465464");
return c;
}
//this is used to validate your user account with provided grant at /connect/token
public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
{
try
{
//get your user model from db (by username - in my case its email)
var user = await _userRepository.FindAsync(1241);
if (user != null)
{
//check if password match - remember to hash password if stored as hash in db
if (true)
{
//set the result
context.Result = new GrantValidationResult(
subject: user.Id.ToString(),
authenticationMethod: "custom",
claims: GetUserClaims(user));
return;
}
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Incorrect password");
return;
}
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "User does not exist.");
return;
}
catch (Exception ex)
{
context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "Invalid username or password");
}
}
}
1 //add identity server 4 2 services.AddIdentityServer() 3 .AddInMemoryApiScopes(Config.GetApiScopes()) 4 .AddInMemoryApiResources(Config.GetApiResources()) 5 .AddInMemoryIdentityResources(Config.GetIdentityResources()) 6 .AddInMemoryClients(Config.GetClients()) 7 .AddDeveloperSigningCredential(persistKey: false) 8 .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()//用戶校驗 9 .AddProfileService<ProfileService>();

參考資料:https://buildmedia.readthedocs.org/media/pdf/identityserver4/release/identityserver4.pdf
源碼地址:https://github.com/imfrank/Galaxy.IdentityServer
