ASP.NET Core JWT 认证

本示例是基于GRPC框架下的认证代码与MVC模式稍有区别,直接上代码 服务端代码如下:

  public void ConfigureServices(IServiceCollection services)
        {
            services.AddGrpc();
            services.AddSingleton<TicketRepository>();

            services.AddAuthorization(options =>
            {
                options.AddPolicy(JwtBearerDefaults.AuthenticationScheme, policy =>
                {
                    policy.AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme);
                    policy.RequireClaim(ClaimTypes.Name);
                });
            });
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                .AddJwtBearer(options =>
                {
                    options.TokenValidationParameters =
                        new TokenValidationParameters
                        {
                            ValidateAudience = true, //验证受众
                            ValidateIssuer = true, //验证签发人
                            ValidateActor = true, //验证签名
                            ValidateLifetime = true, //是否在令牌生存期间验证
                            ValidIssuer = "ExampleServer", //令牌发行者
                            ValidAudience = "ExampleClients", //令牌受众
                            IssuerSigningKey = SecurityKey, //密钥 
                          
                        };
                  
                });
        }
  public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthentication();
            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapGrpcService<TicketerService>();

                endpoints.MapGet("/generateJwtToken", context =>
                {
                    return context.Response.WriteAsync(GenerateJwtToken(context.Request.Query["name"]));
                });
            });
        }
//这里是生成token的代码,当然正常逻辑这里会增加用户密码验证,并做一些权限角色处理
//如正常登录后权限角色写入到redis ,重写 Authorize 特性增加权限验证逻辑
 private string GenerateJwtToken(string name)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new InvalidOperationException("Name is not specified.");
            }

            var claims = new[] { new Claim(ClaimTypes.Name, name) };

            var credentials = new SigningCredentials(SecurityKey, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken("ExampleServer", "ExampleClients", claims, expires: DateTime.Now.AddSeconds(60), signingCredentials: credentials);

            return JwtTokenHandler.WriteToken(token);
        }

客户端调用代码示例:

  //登录验证并得到token  
 private static async Task<string> Authenticate()
        {
            Console.WriteLine($"Authenticating as {Environment.UserName}...");
            var httpClient = new HttpClient();
            var request = new HttpRequestMessage
            {
                RequestUri = new Uri($"{Address}/generateJwtToken?name={HttpUtility.UrlEncode(Environment.UserName)}"),
                Method = HttpMethod.Get,
                Version = new Version(2, 0)
            };
            var tokenResponse = await httpClient.SendAsync(request);
            tokenResponse.EnsureSuccessStatusCode();

            var token = await tokenResponse.Content.ReadAsStringAsync();
            Console.WriteLine("Successfully authenticated.");

            return token;
        }
//调用服务端接口,并加入验证token
  private static async Task PurchaseTicket(Ticketer.TicketerClient client, string? token)
        {
            Console.WriteLine("Purchasing ticket...");
            try
            {
                Metadata? headers = null;
                if (token != null)
                {
                    headers = new Metadata();
                    headers.Add("Authorization", $"Bearer {token}"); 
                    headers.Add("alg", "HS256"); //加密方式
                }

                var response = await client.BuyTicketsAsync(new BuyTicketsRequest { Count = 1 }, headers);

                if (response.Success)
                {
                    Console.WriteLine("Purchase successful.");
                }
                else
                {
                    Console.WriteLine("Purchase failed. No tickets available.");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error purchasing ticket." + Environment.NewLine + ex.ToString());
            }
        }
//服务端代码示例,这里增加  Authorize 特性表示需要验证
//Authorize 的验证规则与验证代理已经在  ConfigureServices 函数配置好。
[Authorize]
        public override Task<BuyTicketsResponse> BuyTickets(BuyTicketsRequest request, ServerCallContext context)
        {
            var user = context.GetHttpContext().User;
           

            return Task.FromResult(new BuyTicketsResponse
            {
                Success = _ticketRepository.BuyTickets(user.Identity.Name!, request.Count)
            });
        }

 参考:https://www.cnblogs.com/7tiny/archive/2019/06/13/11012035.html
           https://cloud.tencent.com/developer/ask/130481

原文地址:https://www.cnblogs.com/ms_senda/p/12457469.html