使用 JWT 实现 .NET 应用的授权与鉴权

使用 JWT 实现 .NET 应用的授权与鉴权

引言

在现代 Web 应用中,JWT(JSON Web Token)是一种流行的身份验证和授权机制。本篇博客将详细介绍如何在 .NET 应用中使用 JWT 来进行用户的登录、授权和鉴权。我们将创建一个简单的 ASP.NET Core Web API 项目,涵盖从用户输入登录名和密码到生成和验证 JWT 的全过程。代码示例将特别详细,确保每一步都清晰易懂。

环境准备

确保你已经安装以下工具:

  • .NET SDK(推荐使用 .NET 6 或更高版本)
  • Visual Studio 2022 或 Visual Studio Code

创建项目

  1. 新建项目:打开终端,执行以下命令创建一个新的 ASP.NET Core Web API 项目。

    bash 复制代码
    dotnet new webapi -n JwtAuthDemo
    cd JwtAuthDemo
  2. 安装 NuGet 包 :为了使用 JWT,我们需要安装 Microsoft.AspNetCore.Authentication.JwtBearer 包。

    bash 复制代码
    dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

配置 JWT

Program.cs 文件中进行 JWT 的配置。

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

var builder = WebApplication.CreateBuilder(args);

// 添加 JWT 认证服务
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = 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:Key"]))
    };
});

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

var app = builder.Build();

// 使用认证中间件
app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();

app.Run();

配置 JWT 相关信息

appsettings.json 文件中添加 JWT 配置项:

json 复制代码
{
  "Jwt": {
    "Key": "YourSuperSecretKeyHere", 
    "Issuer": "JwtAuthDemo",
    "Audience": "JwtAuthDemoUsers"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

创建用户模型

Models 文件夹下创建一个 User.cs 文件:

csharp 复制代码
namespace JwtAuthDemo.Models
{
    public class User
    {
        public string Username { get; set; }
        public string Password { get; set; }
    }
}

创建用户控制器

Controllers 文件夹下创建一个 AuthController.cs 文件:

csharp 复制代码
using JwtAuthDemo.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

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

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

        [HttpPost("login")]
        public IActionResult Login([FromBody] User user)
        {
            // 这里应该有数据库验证用户的逻辑,这里仅为演示用
            if (user.Username != "test" || user.Password != "password")
            {
                return Unauthorized();
            }

            var token = GenerateJwtToken(user.Username);
            return Ok(new { token });
        }

        private string GenerateJwtToken(string username)
        {
            var claims = new[]
            {
                new Claim(JwtRegisteredClaimNames.Sub, username),
                new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
            };

            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:Key"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            var token = new JwtSecurityToken(
                issuer: _configuration["Jwt:Issuer"],
                audience: _configuration["Jwt:Audience"],
                claims: claims,
                expires: DateTime.Now.AddMinutes(30),
                signingCredentials: creds);

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
}

创建受保护的控制器

我们可以创建一个受保护的控制器来验证 JWT:

Controllers 文件夹下创建一个 ValuesController.cs 文件:

csharp 复制代码
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace JwtAuthDemo.Controllers
{
    [Authorize]
    [ApiController]
    [Route("api/[controller]")]
    public class ValuesController : ControllerBase
    {
        [HttpGet]
        public IActionResult GetValues()
        {
            return Ok(new string[] { "value1", "value2" });
        }
    }
}

运行应用

  1. 启动应用:在项目根目录下运行以下命令以启动应用:

    bash 复制代码
    dotnet run
  2. 测试登录功能

    • 使用 Postman 或其他 API 客户端,发送一个 POST 请求到 http://localhost:5000/api/auth/login,请求体为:

      json 复制代码
      {
        "username": "test",
        "password": "password"
      }
    • 如果用户名和密码正确,你将获得一个 JWT token。

  3. 测试受保护的路由

    • 发送一个 GET 请求到 http://localhost:5000/api/values,并在请求头中添加 Authorization 字段:

      复制代码
      Authorization: Bearer {your_token}
    • 如果 token 有效,你将获得 ["value1", "value2"] 的响应。

代码解析

  1. JWT 配置

    • Program.cs 中配置了 JWT 的验证参数,包括签发者、受众以及签名密钥。
  2. 用户模型

    • 创建了一个简单的用户模型来接收登录信息。
  3. 授权控制器

    • AuthController 中的 Login 方法负责验证用户信息并生成 JWT token。
    • GenerateJwtToken 方法负责创建 JWT,包含用户信息的声明(Claims)。
  4. 受保护的控制器

    • ValuesController 需要有效的 JWT 才能访问,利用 [Authorize] 特性进行保护。

总结

本文详细介绍了如何在 .NET 中使用 JWT 进行用户的身份验证和授权。通过简单的示例,展示了如何生成、验证和使用 JWT。在实际应用中,建议将用户的密码存储在数据库中,并使用加密算法进行保护。此外,可以根据需求调整 JWT 的过期时间和内容,以确保安全性和灵活性。

希望这篇博客对你理解 JWT 在 .NET 应用中的使用有所帮助!如果你有任何问题,欢迎在评论区讨论。

相关推荐
波波0072 小时前
每日一题:中间件是如何工作的?
中间件·.net·面试题
无风听海3 小时前
.NET 10之可空引用类型
数据结构·.net
码云数智-园园4 小时前
基于 JSON 配置的 .NET 桌面应用自动更新实现指南
.net
无风听海4 小时前
.NET 10 之dotnet run的功能
.net
岩屿4 小时前
Ubuntu下安装Docker并部署.NET API(二)
运维·docker·容器·.net
码云数智-大飞4 小时前
.NET 中高效实现 List 集合去重的多种方法详解
.net
easyboot4 小时前
使用tinyply.net保存ply格式点云
.net
张人玉4 小时前
WPF 多语言实现完整笔记(.NET 4.7.2)
笔记·.net·wpf·多语言实现·多语言适配
波波0071 天前
Native AOT 能改变什么?.NET 预编译技术深度剖析
开发语言·.net
Crazy Struggle2 天前
.NET 中如何快速实现 List 集合去重?
c#·.net