IdentityServer4 系列 【二】-- 创建鉴权端,使用PostMan获取Token

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的配置都写入数据库中,进行读取。至此鉴权端已经完成,下面介绍资源端开发。

原文地址:https://www.cnblogs.com/youyuan1980/p/14097071.html