.NET Core Web API JWT认证实战指南

1. 简介

JSON Web Token(JWT)是一种开放标准(RFC 7519),用于在网络应用环境间以紧凑、URL 安全的方式传递声明(Claim)。JWT 常用于前后端分离的 Web 应用中,特别是微服务架构和单页应用(SPA)中。本教程将介绍如何在 C# .NET Core Web API 中配置 JWT 认证,帮助开发者实现安全、可扩展的身份验证机制。

2. JWT 结构

JWT 由三部分组成:

  • Header(头部):声明类型(JWT)和所使用的签名算法(如 HS256、RS256)。
  • Payload(载荷):包含声明,通常是用户信息或自定义数据。
  • Signature(签名):通过 Header 和 Payload 加密生成的签名,用于验证 JWT 的真实性和完整性。

3. 准备工作

3.1 创建 .NET Core Web API 项目

使用以下命令创建一个新的 .NET Core Web API 项目:

bash 复制代码
dotnet new webapi -n JwtAuthDemo
cd JwtAuthDemo

3.2 安装必要的 NuGet 包

安装以下 NuGet 包以支持 JWT 认证:

bash 复制代码
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt

4. 配置 JWT 参数

appsettings.json 文件中配置 JWT 相关的参数:

javascript 复制代码
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Jwt": {
    "SecretKey": "your-very-secure-key-at-least-32-characters-long", // 密钥,至少 32 位
    "Issuer": "your-issuer", // 签发者
    "Audience": "your-audience", // 受众
    "ExpirationMinutes": 60 // 过期时间(分钟)
  }
}

5. 配置 JWT 认证服务

Program.cs 文件中配置 JWT 认证服务:

cs 复制代码
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;

var builder = WebApplication.CreateBuilder(args);

// 添加控制器服务
builder.Services.AddControllers();

// 配置 JWT 认证
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true, // 验证签发者
        ValidIssuer = builder.Configuration["Jwt:Issuer"], // 签发者
        ValidateAudience = true, // 验证受众
        ValidAudience = builder.Configuration["Jwt:Audience"], // 受众
        ValidateLifetime = true, // 验证过期时间
        ValidateIssuerSigningKey = true, // 验证签名密钥
        IssuerSigningKey = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"])), // 签名密钥
        ClockSkew = TimeSpan.Zero // 关闭时间偏差容忍
    };
});

// 添加授权服务
builder.Services.AddAuthorization();

var app = builder.Build();

// 启用认证和授权中间件
app.UseAuthentication();
app.UseAuthorization();

// 配置 HTTP 请求管道
app.MapControllers();

app.Run();

6. 创建 JWT 工具类

创建一个工具类 JwtTokenHelper.cs,用于生成 JWT 令牌:

cs 复制代码
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

public class JwtTokenHelper
{
    private readonly IConfiguration _configuration;

    public JwtTokenHelper(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    public string GenerateToken(string username, string role = null)
    {
        // 从配置文件中读取 JWT 参数
        var secretKey = Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]);
        var issuer = _configuration["Jwt:Issuer"];
        var audience = _configuration["Jwt:Audience"];
        var expirationMinutes = int.Parse(_configuration["Jwt:ExpirationMinutes"]);

        // 定义声明(Claims)
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), // 唯一标识
            new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString()) // 签发时间
        };

        // 添加角色声明(如果存在)
        if (!string.IsNullOrEmpty(role))
        {
            claims.Add(new Claim(ClaimTypes.Role, role));
        }

        // 生成签名密钥
        var key = new SymmetricSecurityKey(secretKey);
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        // 创建 JWT 令牌
        var token = new JwtSecurityToken(
            issuer: issuer,
            audience: audience,
            claims: claims,
            expires: DateTime.UtcNow.AddMinutes(expirationMinutes),
            signingCredentials: creds);

        // 返回 JWT 字符串
        return new JwtSecurityTokenHandler().WriteToken(token);
    }
}

7. 创建登录接口

创建一个 AuthController 用于处理用户登录并生成 JWT 令牌:

cs 复制代码
using Microsoft.AspNetCore.Mvc;

[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
    private readonly IConfiguration _configuration;

    public AuthController(IConfiguration configuration)
    {
        _configuration = configuration;
    }

    [HttpPost("login")]
    public IActionResult Login([FromBody] LoginModel model)
    {
        // 这里应验证用户名和密码(示例中简化处理)
        if (model.Username == "admin" && model.Password == "password")
        {
            var tokenHelper = new JwtTokenHelper(_configuration);
            var token = tokenHelper.GenerateToken(model.Username, "Admin");

            return Ok(new
            {
                Token = token
            });
        }

        return Unauthorized();
    }
}

public class LoginModel
{
    public string Username { get; set; }
    public string Password { get; set; }
}

8. 保护 API 接口

使用 [Authorize] 特性标记需要认证的控制器或方法:

cs 复制代码
[ApiController]
[Route("api/[controller]")]
[Authorize] // 整个控制器需要认证
public class SecureController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var username = User.Identity.Name;
        return Ok(new
        {
            Message = $"Hello, {username}",
            Time = DateTime.Now
        });
    }

    [HttpGet("admin")]
    [Authorize(Roles = "Admin")] // 仅 Admin 角色可访问
    public IActionResult AdminOnly()
    {
        return Ok(new
        {
            Message = "This is admin-only content."
        });
    }
}

9. 测试 JWT 认证

9.1 获取 Token

使用 Postman 或其他工具发送 POST 请求到 /api/auth/login,请求体为:

cs 复制代码
{
    "username": "admin",
    "password": "password"
}

成功响应:

cs 复制代码
{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

9.2 访问受保护的接口

在请求头中添加 Authorization 字段,值为 Bearer <token>,例如:

cs 复制代码
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

发送 GET 请求到 /api/secure,成功响应:

cs 复制代码
{
    "message": "Hello, admin",
    "time": "2025-05-20T12:00:00Z"
}

10. 总结

本教程详细介绍了如何在 C# .NET Core Web API 中配置 JWT 认证,包括:

  1. 创建项目并安装必要的 NuGet 包。
  2. 配置 JWT 参数。
  3. 实现 JWT 认证服务。
  4. 创建 JWT 工具类用于生成令牌。
  5. 创建登录接口并返回 JWT 令牌。
  6. 使用 [Authorize] 特性保护 API 接口。
  7. 测试 JWT 认证流程。

通过本教程,开发者可以快速实现基于 JWT 的身份验证机制,提升 Web API 的安全性。

相关推荐
唐青枫14 小时前
别只会看日志:C#.NET SOS 调试扩展从 Dump 到内存泄漏排查
c#·.net
yswenli21 小时前
基于C#开发网站视频嗅探下载工具——BrowserVideoGrabber
c#·videodownload·webvideodownload·videograbber
Lost of 程序猿21 小时前
M2 实战:询价与采购订单聚合落地——跨聚合一致性、领域事件与 Outbox
开发语言·c#·asp.net·.net
Polevne1 天前
C# GRPC 一元与双向流
linux·算法·c#
XiaoZhenHua982 天前
C#工业机器视觉Recipe配方系统设计:多型号、多相机、多工位参数如何统一管理
c#·软件架构·机器视觉·工业自动化·工业软件·recipe
fujisheng6612 天前
FUI 导航实践:拆开 Layer、History、Coverage 与 Cache 的组合语义
c#·unity3d
淡海水2 天前
10-05-高级-模式匹配-CSharp如何改变与数据结构的交互方式
数据结构·算法·c#·模式匹配
XiaoZhenHua982 天前
C# WinForms + 西门子S7 + SQLite + EPPlus生产数据采集系统架构设计
系统架构·sqlite·c#
Lost of 程序猿2 天前
船岸数据同步链路实战:SendFlag、单调版本号与断网三天后的续传
后端·c#·asp.net
cjp5603 天前
012.UG二次开发,UG管道服务器与WPF管道通讯,传输JSON数据
c#