ASP.NET Core - Identity Server4
自定义用户表
public class CustomAccount : Entity<int> { public string Username { get; set; } public string Password { get; set; } public string Phone { get; set; } }
public class Config { public static IEnumerable<IdentityResource> GetIdentityResourceResources() { return new List<IdentityResource> { new IdentityResources.OpenId(), //必须要添加,否则报无效的scope错误 new IdentityResources.Profile() }; } // scopes define the API resources in your system public static IEnumerable<ApiResource> GetApiResources() { return new List<ApiResource> { new ApiResource("api1", "My API") }; } // clients want to access resources (aka scopes) public static IEnumerable<Client> GetClients() { // client credentials client return new List<Client> { new Client { ClientId = "client2", AccessTokenType = AccessTokenType.Jwt, AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, ClientSecrets = { new Secret("secret".Sha256()) }, AllowedScopes = { "api1", IdentityServerConstants.StandardScopes.OpenId, //必须要添加,否则报forbidden错误 IdentityServerConstants.StandardScopes.Profile } } }; } }
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<CustomIdentityDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); // configure identity server with in-memory stores, keys, clients and scopes services.AddIdentityServer() .AddDeveloperSigningCredential() .AddInMemoryIdentityResources(Config.GetIdentityResourceResources()) .AddInMemoryApiResources(Config.GetApiResources()) .AddInMemoryClients(Config.GetClients()) .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>() //.AddCustomAuthorizeRequestValidator<CustomAuthorizeRequestValidator>() .AddProfileService<ProfileService>(); }
public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator { CustomIdentityDbContext Context; public ResourceOwnerPasswordValidator(CustomIdentityDbContext context) { Context = context; } public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) { var user = Context.CustomAccounts .SingleOrDefault(d => d.Username == context.UserName); var c = context.Request.Client.ClientId; if (user == null) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "不存在此用户名!"); return; } if (user.Password != context.Password) { context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "密码错误!"); return; } context.Result = new GrantValidationResult( subject: context.UserName, authenticationMethod: "custom", claims: new Claim[] { new Claim("Id", user.Id.ToString()), new Claim("Username", user.Username), new Claim("Phone", user.Phone) }); } //可以根据需要设置相应的Claim private Claim[] GetUserClaims(CustomAccount user) { return new Claim[] { new Claim("Id", user.Id.ToString()), new Claim("Username", user.Username), new Claim("Phone", user.Phone) }; } }
public class ProfileService : IProfileService { public async Task GetProfileDataAsync(ProfileDataRequestContext context) { try { //depending on the scope accessing the user data. var claims = context.Subject.Claims.ToList(); //set issued claims to return context.IssuedClaims = claims.ToList(); } catch (Exception ex) { //log your error } } public async Task IsActiveAsync(IsActiveContext context) { context.IsActive = true; } }