1、新建.net core 3.1 Web 空项目。
2、Nuget 增加 IdentityServer4(4.1.1)、Autofac(6.0.0)目前使用的版本
3、新建 Config.cs 配置文件 ,源码如下
1 using System.Collections.Generic; 2 using IdentityServer4.Models; 3 namespace IdentityServer 4 { 5 public class Config1 6 { 7 public static IEnumerable<ApiResource> GetApiResources() 8 { 9 return new List<ApiResource> 10 { 11 new ApiResource("userapi"){Scopes={"userscopes"}} 12 }; 13 } 14 15 public static IEnumerable<ApiScope> GetApiScopes() 16 { 17 return new List<ApiScope> 18 { 19 new ApiScope("userscopes") 20 }; 21 } 22 23 public static IEnumerable<Client> GetClients() 24 { 25 return new List<Client>{ 26 new Client(){ 27 ClientId = "webclient", 28 ClientName = "webclient", 29 AllowedGrantTypes = GrantTypes.ResourceOwnerPassword, 30 RequireClientSecret = false, //客户端不需要输入Secret 31 AllowedScopes = {"userscopes"}, 32 ClientSecrets = {new Secret("webclient".Sha256())} 33 } 34 }; 35 } 36 } 37 }
4、由于生产环境中帐号密码取之于数据库中的User表,并不是用于测试的TestUser,所以要增加两个类,一个是验证帐号密码,另一个是帐号另外的一些自定义信息
1 using IdentityModel; 2 using IdentityServer4.Validation; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Security.Claims; 7 using System.Threading.Tasks; 8 using IdentityServer.DbModel; 9 namespace IdentityServer 10 { 11 public class ResourceOwnerPasswordValidatorcs : IResourceOwnerPasswordValidator 12 { 13 public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context) 14 { 15 UserServices userServices = new UserServices(); 16 UserDbModel user = userServices.UserValidator(context.UserName, context.Password); 17 if (user != null) 18 { 19 List<Claim> claims = new List<Claim>() { 20 new Claim("username",user.USERNAME) 21 22 }; 23 context.Result = new GrantValidationResult( 24 context.UserName, 25 OidcConstants.AuthenticationMethods.Password, 26 claims 27 ); 28 } 29 else 30 { 31 context.Result = new GrantValidationResult( 32 IdentityServer4.Models.TokenRequestErrors.InvalidGrant, 33 "invalid custom credential" 34 ); 35 } 36 await Task.CompletedTask; 37 } 38 } 39 }
1 using IdentityServer4.Models; 2 using IdentityServer4.Services; 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Threading.Tasks; 7 8 namespace IdentityServer 9 { 10 /// <summary> 11 /// 获取用户信息并返回给客户端 12 /// </summary> 13 public class ProfileService : IProfileService 14 { 15 /// <summary> 16 /// 获取用户信息 17 /// </summary> 18 /// <param name="context"></param> 19 /// <returns></returns> 20 public Task GetProfileDataAsync(ProfileDataRequestContext context) 21 { 22 return Task.Run(()=> { 23 try 24 { 25 //用户信息 26 var claims = context.Subject.Claims.ToList(); 27 28 //获取用户信息 29 context.IssuedClaims = claims.ToList(); 30 } 31 catch (Exception ex) 32 { 33 //log your error 34 } 35 }); 36 } 37 /// <summary> 38 /// 获取或设置一个值,该值指示主题是否处于活动状态并且可以接收令牌。 39 /// </summary> 40 /// <param name="context"></param> 41 /// <returns></returns> 42 public Task IsActiveAsync(IsActiveContext context) 43 { 44 return Task.Run(()=> { context.IsActive = true; }); 45 } 46 } 47 }
5、修改Startup.cs文件
ConfigureServices 方法中添加IdentityServer设置,与跨域设置
1 //设置IdentityServer4 2 services.AddIdentityServer() 3 .AddInMemoryApiResources(Config.GetApiResources()) 4 .AddInMemoryApiScopes(Config.GetApiScopes()) 5 .AddInMemoryClients(Config.GetClients()) 6 .AddResourceOwnerValidator<ResourceOwnerPasswordValidatorcs>() 7 .AddProfileService<ProfileService>() 8 .AddDeveloperSigningCredential(); 9 10 //设置跨域 11 services.AddCors(options => 12 { 13 options.AddPolicy("any", builder => 14 { 15 builder.WithOrigins("*"); 16 }); 17 });
Configure 方法中添加设置
1 public void Configure(IApplicationBuilder app, IWebHostEnvironment env) 2 { 3 if (env.IsDevelopment()) 4 { 5 app.UseDeveloperExceptionPage(); 6 } 7 8 app.UseCors("any"); 9 10 app.UseRouting(); 11 12 app.UseIdentityServer(); 13 }
6、此时,鉴权端已经使用开发完成,启动即可。
7、使用postman获取Token
以后可以将config的配置都写入数据库中,进行读取。至此鉴权端已经完成,下面介绍资源端开发。