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");
}
}
}
//add identity server 4
services.AddIdentityServer()
.AddInMemoryApiScopes(Config.GetApiScopes())
.AddInMemoryApiResources(Config.GetApiResources())
.AddInMemoryIdentityResources(Config.GetIdentityResources())
.AddInMemoryClients(Config.GetClients())
.AddDeveloperSigningCredential(persistKey: false)
.AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()//用户校验
.AddProfileService<ProfileService>();
image.png
参考资料:https://buildmedia.readthedocs.org/media/pdf/identityserver4/release/identityserver4.pdf
网友评论