当前位置: 首页 > news >正文

C#中如何运用JWT用户认证

一、JWT概述

JSON Web Token(JWT)是一种轻量级的身份认证机制,广泛应用于分布式系统中的用户认证。它通过紧凑的JSON格式存储用户身份信息,并使用数字签名确保信息的完整性和真实性。与传统的基于Session的认证相比,JWT具有无状态、可扩展、跨平台等优势,特别适合于微服务架构和前后端分离的应用场景。

JWT的核心优势在于:

  • 无状态:服务器不需要存储会话信息,减轻服务器负担

  • 跨平台:基于标准JSON格式,可在不同语言和平台间传递

  • 自包含:令牌包含所有必要的用户信息,减少数据库查询

  • 可扩展:支持自定义声明,满足不同业务需求

  • 安全性:通过数字签名确保信息不被篡改

二、JWT工作原理

JWT认证的核心流程如下:

  1. 用户登录:用户提供用户名和密码进行登录

  2. 生成Token:服务器验证成功后,生成包含用户身份信息的JWT令牌

  3. 返回Token:服务器将JWT令牌返回给客户端

  4. 存储Token:客户端存储JWT令牌(通常存储在localStorage或Cookie中)

  5. 请求携带Token:客户端后续请求时,在HTTP头部携带JWT令牌

  6. 验证Token:服务器验证JWT令牌的有效性(签名验证、过期时间检查等)

  7. 处理请求:验证通过后,服务器处理请求并返回结果

JWT认证流程图

+----------+     登录请求      +----------+
|          | -------------->  |          |
| 客户端   |                   | 服务器   |
|          | <--------------  |          |
+----------+   返回JWT令牌     +----------+|                                 ||   携带JWT令牌的请求               || ----------------------------->  ||                                 || <-----------------------------  ||        处理后的响应               |v                                 v

三、JWT结构组成

JWT令牌由三部分组成,用小数点(.)分隔,格式为Header.Payload.Signature:

1. Header(头部)

Header部分包含令牌类型(typ)和加密算法(alg),通常如下:

{"alg": "HS256","typ": "JWT"
}

其中,alg表示使用的加密算法(如HS256、RS256等),typ表示令牌类型。

2. Payload(载荷)

Payload部分包含用户身份信息和其他元数据,分为标准声明和自定义声明:

  • 标准声明

    • iss:令牌颁发者

    • sub:令牌主题(通常是用户ID)

    • aud:令牌受众

    • exp:令牌过期时间

    • iat:令牌颁发时间

    • nbf:令牌生效时间

    • jti:令牌唯一标识符

  • 自定义声明:根据业务需求定义的字段,如用户角色、权限等。

示例:

{"sub": "1234567890","name": "John Doe","role": "admin","exp": 1678900000
}

3. Signature(签名)

Signature部分是对Header和Payload的签名,用于验证令牌的完整性和真实性。服务器使用Header中指定的算法,结合密钥对Header和Payload进行签名:

PlainText
HMACSHA256(base64UrlEncode(header) + "." +base64UrlEncode(payload),secretKey
)

四、C#中实现JWT认证

1. 安装必要的包

在C#项目中,我们需要安装以下NuGet包:

  • System.IdentityModel.Tokens.Jwt:用于生成和验证JWT令牌

  • Microsoft.AspNetCore.Authentication.JwtBearer:提供JWT身份验证中间件

Install-Package System.IdentityModel.Tokens.Jwt
Install-Package Microsoft.AspNetCore.
Authentication.JwtBearer

2. 配置JWT认证服务

在Program.cs文件中,添加JWT认证服务配置:

Program.cs 
using Microsoft.AspNetCore.Authentication.
JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
​
var builder = WebApplication.CreateBuilder(args);
​
// 添加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"])) // 签名密钥};});
​
// 添加授权服务
builder.Services.AddAuthorization();
​
var app = builder.Build();
​
// 使用认证和授权中间件
app.UseAuthentication();
app.UseAuthorization();
​
app.MapControllers();
app.Run();

3. 配置appsettings.json

在appsettings.json文件中添加JWT相关配置:

appsettings.json
应用
{"Jwt": {"Issuer": "YourIssuer","Audience": "YourAudience","SecretKey": "YourSecretKeyHereShouldBeLongEnough"},"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*"
}

4. 生成JWT令牌

创建一个AuthController,实现用户登录和生成JWT令牌的功能:

AuthController.cs
​
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
​
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{private readonly IConfiguration _configuration;
​public AuthController(IConfiguration configuration){_configuration = configuration;}
​[HttpPost("login")]public IActionResult Login([FromBody] LoginRequest request){// 验证用户凭据(实际应用中应查询数据库)if (request.Username == "admin" && request.Password == "password"){// 创建用户声明var claims = new[]{new Claim(ClaimTypes.Name, request.Username),new Claim(ClaimTypes.Role, "admin"),new Claim(JwtRegisteredClaimNames.Sub, "1234567890"),new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())};
​// 生成对称安全密钥var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
​// 生成签名凭据var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
​// 创建JWT令牌var token = new JwtSecurityToken(issuer: _configuration["Jwt:Issuer"],audience: _configuration["Jwt:Audience"],claims: claims,expires: DateTime.Now.AddMinutes(30),signingCredentials: creds);
​// 返回JWT令牌return Ok(new{token = new JwtSecurityTokenHandler().WriteToken(token),expiration = token.ValidTo});}
​return Unauthorized();}
}
​
public class LoginRequest
{public string Username { get; set; }public string Password { get; set; }
}

5. 保护API端点

使用[Authorize]属性保护API端点,只有携带有效JWT令牌的请求才能访问:

ValuesController.cs
​
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
​
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class ValuesController : ControllerBase
{[HttpGet]public IActionResult Get(){return Ok(new string[] { "value1", "value2" });}
​[HttpGet("{id}")][Authorize(Roles = "admin")]public IActionResult Get(int id){return Ok($"value {id}");}
}

五、JWT认证的注意事项

  1. 密钥安全:确保JWT密钥安全存储,避免硬编码在代码中

  2. 令牌过期时间:设置合理的令牌过期时间,平衡安全性和用户体验

  3. HTTPS传输:使用HTTPS协议传输JWT令牌,防止中间人攻击

  4. 令牌刷新机制:实现令牌刷新机制,避免用户频繁登录

  5. 敏感信息:不要在JWT中存储敏感信息,如密码等

  6. 权限控制:结合角色和权限声明,实现细粒度的访问控制

http://www.dtcms.com/a/325618.html

相关文章:

  • AT24C02C-SSHM-T用法
  • 什么情况下会导致日本服务器变慢?解决办法
  • 系统编程——消息队列
  • 前端实现 MD5 + AES 加密的安全登录请求
  • Nacos-1--什么是Nacos?
  • 疫情可视化:基孔肯雅热风险地图实战解析
  • Dubbo从入门到实战:分布式服务开发指南
  • WPF之绑定!
  • OpenCV计算机视觉实战(19)——特征描述符详解
  • 玩转Docker | 使用Docker部署Trilium Notes知识库工具
  • typecho博客设置浏览器标签页图标icon
  • 石材 × 设计:解锁永恒材质的四大灵感密码
  • 数据结构 双链表与LinkedList
  • 18.WEB 服务器
  • 超算中心的一台服务器上有多少个CPU,多少个核?
  • JVM基础【Java】
  • 力扣164:最大间距
  • 深入理解与灵活应用 std::optional
  • vue3中的子组件向父组件通信和父组件向子组件通信
  • python --nacos相关
  • MSE ZooKeeper:Flink高可用架构的企业级选择
  • 《图解技术体系》New generation CMDB resource model framework
  • 自然语言处理实战:用LSTM打造武侠小说生成器
  • 【AI论文】R-Zero:从零数据起步的自进化推理大语言模型
  • JavaScript 中如何实现大文件并行下载
  • AI(2)-神经网络(激活函数)
  • 支持小语种的在线客服系统,自动翻译双方语言,适合对接跨境海外客户
  • NY185NY190美光固态闪存NY193NY195
  • 《深度剖析前端框架中错误边界:异常处理的基石与进阶》
  • pom.xml父子模块配置