Demo https://github.com/MartinAaron/data_collection
1、自定义身份校验
public static IEnumerable<Client> GetClients(){return new List<Client>{//grant_type basicnew Client{ClientId = "xczx",AccessTokenLifetime = 36000,AllowedGrantTypes = GrantTypes.ClientCredentials,ClientSecrets ={new Secret("xczx".Sha256()),},AllowedScopes = {"api"}},// grant_type passwordnew Client(){ClientId = "client",AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,ClientSecrets ={new Secret("_123456".Sha256())},AllowedScopes ={"api", IdentityServerConstants.StandardScopes.OpenId,IdentityServerConstants.StandardScopes.Profile}}};}// ...//StartUp.csservices.AddScoped<IResourceOwnerPasswordValidator, ResourceOwnerPasswordValidator>();services.AddScoped<IProfileService, ProfileServices>();var builder = services.AddIdentityServer().AddInMemoryClients(Conf.GetClients()).AddInMemoryIdentityResources(Conf.GetIdentityResourceResources()).AddResourceOwnerValidator<ResourceOwnerPasswordValidator>().AddInMemoryApiResources(Conf.GetApiResources()).AddInMemoryApiScopes(Conf.ApiScopes).AddProfileService<ProfileServices>();
使用 ResourceOwnerPassword 类型 需要实现 IResourceOwnerPasswordValidator与IProfileService接口,进行业务密码验证与身份获取。
//ResourceOwnerPasswordValidatorpublic ResourceOwnerPasswordValidator(UserRepository userRepository){_userRepository = userRepository;}private readonly UserRepository _userRepository;public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context){var user = await _userRepository.GetListByField("account", context.UserName);if (user.Count == 0){context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,"账号输入错误");}else if (user.First().Password != context.Password.ToMD5String()){context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant,"密码错误");} else{context.Result = new GrantValidationResult(subject: context.UserName,authenticationMethod: OidcConstants.AuthenticationMethods.Password);} }
//ProfileServices
public ProfileServices(UserRepository userRepository)
{_userRepository = userRepository;
}private readonly UserRepository _userRepository;public async Task<List<Claim>> GetClaimsFromUserAsync(User user)
{var claims = new List<Claim>{new Claim(JwtClaimTypes.Id, user.Id.ToString()),new Claim(JwtClaimTypes.NickName, user.RealName),new Claim(type: JwtClaimTypes.Role, user.RoleId ?? ""),new Claim(type: JwtClaimTypes.Profile, user.DepartmentId ?? "")};await Task.CompletedTask;return claims;
}/// <summary>
/// http://localhost:5002/connect/userinfo
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task GetProfileDataAsync(ProfileDataRequestContext context)
{var userAccount = context.Subject.Claims.FirstOrDefault(c => c.Type == "sub").Value;var user = await _userRepository.GetListByField("account", userAccount);context.IssuedClaims = await GetClaimsFromUserAsync(user.First());
}public async Task IsActiveAsync(IsActiveContext context)
{var userAccount = context.Subject.Claims.FirstOrDefault(c => c.Type == "sub").Value;var user = await _userRepository.GetListByField("account", userAccount);context.IsActive = user.Any();
}
别忘记注入两个实现类
获取Token http://localhost:5002/connect/token
通过 access_token 获取用户信息
这里 token 不加 Bearer和空格