IdentityServer4 实现Token认证登录

参考链接

1.创建环境

IdentityServer4环境搭建
下面的环境是基于VS Stuido环境测试

2.修改IdentityServer4配置文件

    public static class Config
    {
        public static IEnumerable<IdentityResource> Ids =>
            new IdentityResource[]
          //new List<IdentityResource>
            {
                new IdentityResources.OpenId(),
                new IdentityResources.Profile()
            };

        public static IEnumerable<ApiResource> Apis =>
            new ApiResource[]
            {
                 new ApiResource("api1","My Api")
            };

        public static IEnumerable<Client> Clients =>
            new Client[]
            {
              new Client
                    {
                        ///
                        ClientId = "client",
                              



                        // 没有交互性用户,使用 客户端模式 进行身份验证。
                        //AllowedGrantTypes = GrantTypes.ClientCredentials,

                        //登录验证
                        AllowedGrantTypes = GrantTypes.ResourceOwnerPassword,
                       
                        // 用于认证的密码
                        ClientSecrets =
                        {
                            new Secret("123456789".Sha256())
                        },
                        // 客户端有权访问的范围(Scopes)
                        //AllowedScopes = { "api1" }
                  AllowedScopes = { "api1",IdentityServerConstants.StandardScopes.OpenId, //必须要添加,否则报forbidden错误
                  IdentityServerConstants.StandardScopes.Profile},




                    }

            };

    }

3.修改 Starp up文件。

注意,这边为了偷懒,将一些配置文件都放在这里面了。这个仅供测试使用

   public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            //修改的
            services.AddIdentityServer()
                .AddDeveloperSigningCredential()
                    .AddInMemoryApiResources(Config.Apis)
                    .AddInMemoryIdentityResources(Config.Ids)
                    .AddInMemoryClients(Config.Clients)
              .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
                .AddProfileService<ProfileService>();

            //services.AddIdentityServer()
            //   .AddDeveloperSigningCredential()
            //   .AddInMemoryIdentityResources(Config.GetIdentityResourceResources())
            //   .AddInMemoryApiResources(Config.GetApiResources())
            //   .AddInMemoryClients(Config.GetClients())
            //   .AddResourceOwnerValidator<ResourceOwnerPasswordValidator>()
            //   .AddProfileService<ProfileService>();


            //增加权限访问
            services.AddAuthentication(config =>
            {
                config.DefaultScheme = "Bearer"; //这个是access_token的类型,获取access_token的时候返回参数中的token_type一致
            }).AddIdentityServerAuthentication(option =>
            {
                option.ApiName = "api1"; //资源名称,认证服务注册的资源列表名称一致,
                option.Authority = "http://localhost:1863"; //认证服务的url
                option.RequireHttpsMetadata = false; //是否启用https

            });


        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseIdentityServer(); //修改的,登录获取token
            app.UseAuthentication();//修改的,增加权限认证

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }



    //因为要使用登录的时候要使用数据中保存的用户进行验证,要实IResourceOwnerPasswordValidator接口:
    public class ResourceOwnerPasswordValidator : IResourceOwnerPasswordValidator
    {
        public ResourceOwnerPasswordValidator()
        {

        }

        public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            //根据context.UserName和context.Password与数据库的数据做校验,判断是否合法
            if (context.UserName == "wjk" && context.Password == "123")
            {
                context.Result = new GrantValidationResult(
                 subject: context.UserName,
                 authenticationMethod: "custom",
                 claims: GetUserClaims());
            }
            else
            {

                //验证失败
                context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, "invalid custom credential");
            }
        }
        //可以根据需要设置相应的Claim
        private Claim[] GetUserClaims()
        {
            return new Claim[]
            {
            new Claim("UserId", 1.ToString()),
            new Claim(JwtClaimTypes.Name,"wjk"),
            new Claim(JwtClaimTypes.GivenName, "jaycewu"),
            new Claim(JwtClaimTypes.FamilyName, "yyy"),
            new Claim(JwtClaimTypes.Email, "[email protected]"),
            new Claim(JwtClaimTypes.Role,"admin")
            };
        }
    
    }
    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;
        }
    }

postman get 访问 :http://localhost:1863/connect/userinfo 记得带上token

猜你喜欢

转载自www.cnblogs.com/Alex-Mercer/p/12566328.html
今日推荐