• 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

  • 相关阅读:
    Java知多少(81)框架窗口基础
    Java知多少(80)图形界面设计基础
    Java知多少(79)哈希表及其应用
    Java知多少(78)Java向量(Vector)及其应用
    Java知多少(中)
    Java知多少(77)日期和时间类
    Java知多少(76)语言包(java.lang)简介
    Java知多少(75)Object类
    Java知多少(74)基础类库
    Java知多少(73)文件的压缩处理
  • 原文地址:https://www.cnblogs.com/ms_senda/p/12457469.html
Copyright © 2020-2023  润新知