Day24:JWT 权限验证中间件 + 认证授权全套实战(笔记 + 面试题 + 落地步骤)

一、今日学习目标

  1. ASP.NET Core 认证、授权核心概念
  2. 配置 JWT 全局认证中间件
  3. [Authorize] / [AllowAnonymous] 使用
  4. 角色认证、策略认证基础用法
  5. 接口自动鉴权:无 Token/Token 非法 / 过期 自动 401
  6. 完成:登录后带 Token 请求需要授权的接口

二、核心概念极简理解

1. 认证 Authentication(你是谁?

校验 JWT 是否合法、是否过期、签名是否正确,解析出用户身份信息。

2. 授权 Authorization(你能干嘛?

认证通过后,判断你有没有权限访问当前接口(角色、策略、资源)。

3. 两个特性

  • [Authorize]必须登录带 Token 才能访问
  • [AllowAnonymous]匿名放行,不需要 Token

三、高频面试题 + 标准答案

1. 认证和授权有什么区别?

认证 :校验身份,确认你是谁(JWT 验签、解析用户)。
授权:确认你能访问哪些接口(角色、权限、策略控制)。

2. Authorize 作用?

标识接口 / 控制器需要登录认证,请求必须携带合法 JWT Token,否则直接返回 401 未授权。

3. AllowAnonymous 作用?

跳过 JWT 认证,允许匿名访问,比如:登录、注册、验证码接口。

4. ASP.NET Core JWT 鉴权原理?

  1. 请求头携带 Authorization: Bearer Token
  2. JWT 认证中间件自动拦截
  3. 验签、校验过期、解析载荷生成 ClaimsPrincipal
  4. 后续授权、接口可获取当前登录用户信息

5. Token 过期、篡改会怎么样?

中间件自动校验失败,直接返回 401 Unauthorized,不会进入接口业务代码。

6. 为什么用 Bearer 前缀?

标准 HTTP 认证方案,标识这是Bearer 令牌,区分 Basic、Digest 等认证方式。

四、落地配置步骤(DDD 架构直接可用)

1. 先确保已安装 NuGet

复制代码
Microsoft.IdentityModel.Tokens
System.IdentityModel.Tokens.Jwt

2. appsettings 保留 Jwt 配置

cs 复制代码
"Jwt": {
  "Secret": "你的超长密钥字符串",
  "Issuer": "Admin.API",
  "Audience": "Admin.Client",
  "ExpireMinutes": 120
}

3. Program.cs 注册 JWT 认证授权中间件

cs 复制代码
// 读取Jwt配置
var jwtSection = builder.Configuration.GetSection("Jwt");
var secretKey = jwtSection["Secret"]!;
var issuer = jwtSection["Issuer"]!;
var audience = jwtSection["Audience"]!;

// 添加认证
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 校验签发者
            ValidateIssuer = true,
            // 校验受众
            ValidateAudience = true,
            // 校验过期时间
            ValidateLifetime = true,
            // 校验签名密钥
            ValidateIssuerSigningKey = true,

            ValidIssuer = issuer,
            ValidAudience = audience,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)),
            // 不允许时间偏移
            ClockSkew = TimeSpan.Zero
        };
    });

// 启用授权
builder.Services.AddAuthorization();

4. 启用中间件顺序(必须按这个顺序)

cs 复制代码
// 先认证
app.UseAuthentication();
// 后授权
app.UseAuthorization();

顺序不能乱:认证 → 授权 → 路由

五、特性实际使用

1. 登录接口匿名放行

cs 复制代码
[HttpPost("login")]
[AllowAnonymous]
public async Task<ActionResult<R<LoginVo>>> Login([FromBody] LoginDto dto)
{
    // ...
}

2. 整个控制器都需要登录

cs 复制代码
[ApiController]
[Route("api/[controller]")]
[Authorize]
public class UserController : ControllerBase
{
    // 所有接口都必须带Token
}

3. 单个接口需要登录

cs 复制代码
[HttpGet("page")]
[Authorize]
public async Task<ActionResult<...>> Page(...)
{

}

4. 角色认证(基础用法)

生成 JWT 时带入角色 Claim,接口限制角色:

cs 复制代码
[Authorize(Roles = "Admin")]

六、Postman 带 Token 请求方式

  1. 先调用登录接口,拿到 Token
  2. 切换到 Authorization → Type 选 Bearer Token
  3. 把登录返回的 Token 粘贴进去
  4. 访问加了 [Authorize] 的接口,正常通行
  5. 不带 Token / 乱填 Token / 过期 Token → 直接 401

七、今日练习任务

  1. 配置好 JWT 认证中间件,中间件顺序正确
  2. 登录接口加 [AllowAnonymous]
  3. 用户分页、新增、修改接口加 [Authorize]
  4. Postman 测试:
    • 不带 Token 访问 → 401
    • 带合法 Token 访问 → 正常返回
    • 篡改 Token / 过期 Token → 401
  5. 学会从接口中获取当前登录用户 ID、账号

八、拓展:控制器中获取当前登录用户

cs 复制代码
// 获取用户ID
var userId = User.Claims.FirstOrDefault(c => c.Type == "UserId")?.Value;
// 获取登录账号
var account = User.Identity?.Name;
相关推荐
FellAveal1 天前
【Go语言入门学习笔记】Part18.工作池与WaitGroup(也即协程池)
笔记·学习·golang
xqqxqxxq1 天前
Java Socket 多人聊天室(私聊+群聊)技术笔记(V4版本)
java·网络·笔记
龙仔7251 天前
人大金仓OS_Core数据库自动备份实施笔记(银河麒麟Linux)
linux·数据库·笔记·备份·人大金仓
Z5998178411 天前
c#软件开发学习笔记--Modbus-RTU通讯
笔记·学习·c#
quanjui1 天前
【医学尝试】基于Segment Anything Model的医学图像分割研究:眼底OCT与X线胸片微调实战
人工智能·笔记·学习
小黄蚁1 天前
FreeRTOS学习笔记(十二)
笔记·学习
茯苓gao1 天前
嵌入式开发笔记:电机参数辨识与自学习完全指南——从电气参数到机械特性的深度解析
笔记·嵌入式硬件·学习
优化Henry1 天前
学习笔记之VoNR语音业务注册流程
网络·笔记·学习·5g·信息与通信
摇滚侠1 天前
《RocketMQ 官网》阅读笔记 RocketMQ 订阅 (Subscription)
笔记·rocketmq
风曦Kisaki1 天前
Kubernetes(K8s)笔记Day03: Pod命名空间,标签,Pod 的调度,污点与容忍度,Pod 常见状态和重启策略,Pod 生命周期
linux·运维·笔记·docker·云原生·容器·kubernetes