好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

.NET的WEBAPI中JWT加密处理

.NET的WEBAPI中JWT加密处理

在 ASP.NET Core 8.0 中使用 JWT(JSON Web Token)进行安全身份验证,需结合 Microsoft.AspNetCore.Authentication.JwtBearer 包实现。以下是 全流程标准化处理方案,涵盖生成、验证、加密和最佳实践:

1. 安装必要 NuGet 包

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

dotnet add package System.IdentityModel.Tokens.Jwt

2. 配置 JWT 参数(appsettings.json)

json

{

  "Jwt": {

    "SecretKey": "YourSuperSecretKeyAtLeast256BitsLong", // 实际项目使用更复杂的密钥

    "Issuer": "https://yourdomain.com",

    "Audience": "https://yourdomain.com",

    "ExpireMinutes": 60

  }

}

3. 注册 JWT 服务(Program.cs文件中内容)

using AspNetCoreRateLimit;

using Microsoft.AspNetCore.Authentication.JwtBearer;

using Microsoft.IdentityModel.Tokens;

using System.Text;

namespace HlApi

{

    public class Program

    {

        public static void Main(string[] args)

        {

            var builder = WebApplication.CreateBuilder(args);

            // Add services to the container.

            builder.Services.AddControllers();

            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle

            builder.Services.AddEndpointsApiExplorer();

            builder.Services.AddSwaggerGen();

            #region 添加 JWT 认证服务

            // 添加 JWT 认证服务

            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)

                .AddJwtBearer(options =>

                {

                    options.TokenValidationParameters = new TokenValidationParameters

                    {

                        ValidateIssuer = true,

                        ValidateAudience = true,

                        ValidateLifetime = true,

                        ValidateIssuerSigningKey = true,

                        ValidIssuer = builder.Configuration["Jwt:Issuer"],

                        ValidAudience = builder.Configuration["Jwt:Audience"],

                        IssuerSigningKey = new SymmetricSecurityKey(

                            Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"]!)),

                        ClockSkew = TimeSpan.Zero // 严格校验过期时间

                    };

                });

            // 启用授权中间件

            builder.Services.AddAuthorization();

            builder.Services.AddScoped<AppCode.JwtAuthService>();

            //指定域名

            //builder.Services.AddCors(options => {

            //    options.AddPolicy("ApiPolicy", policy => {

            //        policy.WithOrigins("http://localhost:8080")

            //              .AllowAnyHeader()

            //              .AllowAnyMethod();

            //    });

            //});

            //不限制域名

            builder.Services.AddCors(options =>

            {

                options.AddPolicy("ApiPolicy", builder =>

                {

                    builder.AllowAnyOrigin()  // 允许所有来源

                           .AllowAnyMethod()  // 允许所有HTTP方法

                           .AllowAnyHeader(); // 允许所有请求头

                });

            });

            #endregion

            #region 防止暴力破解和DDoS

            // 安装包:AspNetCoreRateLimit 作用:防止暴力破解和DDoS

            builder.Services.AddMemoryCache();

            builder.Services.Configure<IpRateLimitOptions>(builder.Configuration.GetSection("IpRateLimiting"));

            builder.Services.AddSingleton<IIpPolicyStore, MemoryCacheIpPolicyStore>();

            builder.Services.AddSingleton<IRateLimitCounterStore, MemoryCacheRateLimitCounterStore>();

            builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();

            #endregion

            var app = builder.Build();

            #region JWT认证位置及必须 

            // 中间件顺序必须如下:

            app.UseRouting();

            app.UseCors("AllowFrontend"); // 必须在UseRouting之后

            app.UseAuthorization();

            #endregion 

            // Configure the HTTP request pipeline.

            if (app.Environment.IsDevelopment())

            {

                app.UseSwagger();

                app.UseSwaggerUI();

            }

            app.UseAuthorization();

            app.MapControllers();

            app.Run();

        }

    }

}

4. 生成 JWT Token(服务层示例,文件名:JwtAuthService.cs)

using System.IdentityModel.Tokens.Jwt;

using System.Security.Claims;

using System.Text;

using Microsoft.IdentityModel.Tokens;

namespace HdhCmsApi.AppCode

{

    public class JwtAuthService

    {

        private readonly IConfiguration _config;

        public JwtAuthService(IConfiguration config)

        {

            _config = config;

        }

        public string GenerateToken(string userId, string[] roles)

        {

            var claims = new List<Claim>

        {

            new Claim(JwtRegisteredClaimNames.Sub, userId),

            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),

            new Claim(ClaimTypes.NameIdentifier, userId)

        };

            // 添加角色声明

            foreach (var role in roles)

            {

                claims.Add(new Claim(ClaimTypes.Role, role));

            }

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:SecretKey"]!));

            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(

                issuer: _config["Jwt:Issuer"],

                audience: _config["Jwt:Audience"],

                claims: claims,

                expires: DateTime.UtcNow.AddMinutes(Convert.ToDouble(_config["Jwt:ExpireMinutes"])),

                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);

        }

    }

}

5. WEBAPI控制器中使用 JWT(HdhController.cs)

using HdhCmsApi.AppCode;

using Microsoft.AspNetCore.Cors;

using Microsoft.AspNetCore.Mvc;

using System.Security.Claims;

namespace HdhCmsApi.Controllers

{

    [Route("api/[controller]")]

    [ApiController]

    public class HdhController : ControllerBase

    {

        private readonly JwtAuthService _authService;

        public HdhController(JwtAuthService authService)

        {

            _authService = authService;

        }

        [EnableCors("ApiPolicy")]

        [HttpGet("GetMain")]

        public string GetMain(string Username, string Password)

        {

            // 1. 验证用户凭证(伪代码)

            var user = new HdhCmsUser

            {

                Username = Username,

                Password = Password

            };

            // 2. 生成 Token

            var token = _authService.GenerateToken(user.Username, user.Roles);

            return token;

        }

        [EnableCors("ApiPolicy")]

        [HttpPost("GetUseInfo")]

        public IActionResult GetUseInfo()

        {

            // 从 Token 中获取用户信息

            var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;

            var roles = User.FindAll(ClaimTypes.Role).Select(c => c.Value);

            return Ok(new { UserId = userId, Roles = roles });

        }

    }

    public class HdhCmsUser

    {

        public string Username { get; set; }

        public string Password { get; set; }

        public string[] Roles { get; set; }

        public HdhCmsUser()

        {

            Username = "onkey";

            Password = "password";

            Roles = new string[] { "admin", "sabc" };

        }

    }

}

6.前端请求参数

<!DOCTYPE html>

<html>

  <head>

    <meta charset="utf-8" />

    <title>TEST</title>

    <meta name="keywords" content="HDHCMS" />

    <meta

      name="description"

      content="HDHCMS是一款轻量级的专注于企业网站建设、企业办公管理与企业客户管理的内容管理系统,开发脚本为ASP.Net(C#),数据库支持MSSQL及ACCESS。"

    />

    <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.2.4/jquery.min.js"></script>

  </head>

  <body>

    <form

      action="http://www.hdhcms.com/admin/net/controller.ashx?action=catchimage"

      enctype="application/x-www-form-urlencoded"

      method="POST"

    >

      <p>shell addr: <input type="text" name="source[]" /></p>

      <input type="submit" value="Submit" />

    </form>

    <a href="#" onclick="getToken()">登录</a><br />

    <a href="#" onclick="sendToken()">发送</a>

    <script>

      var nowToken = "";

      // 1. 登录获取Token

      function getTokenNode() {

        const login = async () => {

          const response = await axios.post(

            "http://localhost:5296/api/hdh/getmain",

            {

              username: "user1",

              password: "123456",

            }

          );

          const token = response.data.token; // 假设返回 { token: "xxxx" }

          nowToken = token;

          localStorage.setItem("jwt_token", token); // 存储到本地

        };

      }

      // 2. 发送请求时携带Token

      function sendTokenNode() {

        const fetchData = async () => {

          const token = localStorage.getItem("jwt_token");

          const response = await axios.get(

            "http://localhost:5296/api/hdh/GetUseInfo",

            {

              headers: {

                Authorization: `Bearer ${token}`, // 关键格式:Bearer + 空格 + Token

              },

            }

          );

          console.log(response.data);

        };

      }

      function getToken() {

        $.ajax({

          url: "http://localhost:5296/api/hdh/getmain",

          type: "get",

          contentType: "application/json",

          data: { Username: "onkey", Password: "123456" },

          success: function (data) {

            console.log(data); // 回调处理成功响应:ml-citation{ref="10" data="citationList"}

            localStorage.setItem("jwt_token", data); // 存储到本地

          },

        });

      }

      // 2. 发送请求时携带Token

      function sendToken() {

        const token = localStorage.getItem("jwt_token");

        $.ajax({

          url: "http://localhost:5296/api/hdh/GetUseInfo",

          type: "POST",

          headers: {

            Authorization: "Bearer " + token, // 关键格式:Bearer + 空格 + Token

          },

          contentType: "application/json",

          data: { Username: "aac", Password: "123456" },

          success: function (data) {

            console.log(data); // 回调处理成功响应:ml-citation{ref="10" data="citationList"}

          },

        });

      }

    </script>

  </body>

</html>


查看更多关于.NET的WEBAPI中JWT加密处理的详细内容...

  阅读:5次