.NET 中使用 JWT 进行身份验证和授权

在 .NET 中使用 JWT 进行身份验证和授权

在现代 Web 开发中,身份验证和授权是至关重要的,尤其是在构建分布式应用和微服务时。JSON Web Token (JWT) 是一种非常流行的解决方案,用于在不同系统之间传递身份验证信息和授权信息。在本文中,我们将探讨如何在 .NET 中使用 JWT,介绍如何创建、签名、验证和解析 JWT。

什么是 JWT?

JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在网络应用环境中安全地传输信息。JWT 是通过将信息编码成 JSON 格式并进行加密和签名来确保信息的安全性。JWT 主要由三部分组成:

  1. Header(头部):包含算法信息(如 HMAC SHA256 或 RSA)和 token 类型(通常为 JWT)。
  2. Payload(负载):存放需要传递的声明(Claims),如用户信息、过期时间等。
  3. Signature(签名):用于验证 token 的真实性,确保信息未被篡改。

JWT 采用以下格式:

xxxxx.yyyyy.zzzzz

JWT 常用于 Web API 的身份验证中,尤其是作为 Bearer Token 来认证用户身份。


1. 安装所需的 NuGet 包

在 .NET 中使用 JWT,首先需要安装相关的 NuGet 包。常用的包包括 System.IdentityModel.Tokens.JwtMicrosoft.AspNetCore.Authentication.JwtBearer

在终端或包管理器控制台中,运行以下命令来安装这些包:

dotnet add package System.IdentityModel.Tokens.Jwt
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer

2. JWT 的基本结构

JWT 是一个包含三部分的字符串,通常如下所示:

xxxxx.yyyyy.zzzzz
  • Header(头部):描述了签名的算法(例如:HMAC SHA256)。
  • Payload(负载):存储数据,如用户的身份信息(比如用户ID、用户名、角色等)。
  • Signature(签名):用于验证数据的完整性,防止数据在传输过程中被篡改。

3. 在 .NET 中生成 JWT

生成 JWT 通常需要使用 JwtSecurityTokenHandler 类,并指定密钥和相关声明。

示例:生成 JWT

using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.Text;

public class JwtHelper
{
    private static string SecretKey = "your-256-bit-secret";  // 用于签名的密钥

    public static string GenerateToken(string username)
    {
        var claims = new[] {
            new Claim(JwtRegisteredClaimNames.Sub, username),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
            new Claim(JwtRegisteredClaimNames.Iat, DateTime.UtcNow.ToString(), ClaimValueTypes.DateTime),
        };

        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecretKey));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

        var token = new JwtSecurityToken(
            issuer: "yourdomain.com",  // 可选,发行者
            audience: "yourdomain.com",  // 可选,受众
            claims: claims,
            expires: DateTime.Now.AddHours(1),  // 设置 token 的过期时间
            signingCredentials: creds
        );

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

解释:

  1. Claims(声明):声明包含我们需要传递的数据。在这个例子中,我们传递了用户的 sub(主题)、jti(JWT ID)和 iat(签发时间)。
  2. SigningCredentials(签名凭证):这部分定义了签名算法和密钥。我们使用了 HMAC SHA256 算法进行签名。
  3. JwtSecurityTokenHandler:该类负责将 JwtSecurityToken 对象转换为 JWT 字符串。

4. 在 ASP.NET Core 中验证 JWT

为了确保请求来自已授权的用户,我们可以在 Web API 中配置 JWT Bearer 认证中间件。

配置 JWT Bearer 认证

Startup.cs 文件的 ConfigureServices 方法中,我们需要配置 JWT Bearer 认证中间件来验证传入的 JWT。

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = "yourdomain.com",  // 配置合法的发行者
                ValidAudience = "yourdomain.com",  // 配置合法的受众
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-256-bit-secret"))  // 配置密钥
            };
        });

    services.AddControllers();
}

在这里,我们设置了:

  • ValidateIssuer:验证 JWT 的发行者是否合法。
  • ValidateAudience:验证 JWT 的受众是否合法。
  • ValidateLifetime:验证 JWT 是否已过期。
  • IssuerSigningKey:设置用于签名验证的密钥。

5. 启用身份验证和授权

Startup.cs 文件的 Configure 方法中,我们需要启用身份验证和授权中间件:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

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

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

6. 使用 JWT 进行授权

我们可以使用 [Authorize] 特性来保护需要身份验证的 API 控制器或方法。例如,保护一个获取用户信息的 API:

[Authorize]
[HttpGet("protected")]
public IActionResult GetProtectedData()
{
    return Ok(new { message = "This is a protected resource" });
}

只有持有有效 JWT 的用户才能访问这个 API。


7. 解析 JWT

在需要解析 JWT 的场景中,可以通过 JwtSecurityTokenHandler 类来验证和解析 token。

示例:解析 JWT

public static ClaimsPrincipal ValidateToken(string token)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var key = Encoding.UTF8.GetBytes("your-256-bit-secret");

    try
    {
        var principal = tokenHandler.ValidateToken(token, new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = "yourdomain.com",
            ValidAudience = "yourdomain.com",
            IssuerSigningKey = new SymmetricSecurityKey(key)
        }, out SecurityToken validatedToken);

        return principal;
    }
    catch (Exception)
    {
        return null;  // 验证失败,返回 null
    }
}

该方法会验证 JWT 的签名、发行者、受众和过期时间等信息,确保 token 的有效性。


8. 总结

在本文中,我们介绍了如何在 .NET 中使用 JWT 进行身份验证和授权。以下是主要步骤:

  1. 生成 JWT:通过设置声明、签名密钥等信息生成 JWT。
  2. 验证 JWT:在 API 中配置 JWT Bearer 认证中间件,确保请求者的身份。
  3. 授权:通过 [Authorize] 特性来保护需要身份验证的资源。
  4. 解析 JWT:验证和解析 JWT,获取其中的声明信息。

JWT 是实现现代 Web 应用程序中身份验证和授权的有效方案,特别适用于基于 token 的认证机制,如 OAuth 2.0 和 OpenID Connect。通过上述方法,您可以在 .NET 环境中轻松集成 JWT 认证和授权功能,确保您的 API 安全可靠。

posted @ 2025-01-17 11:12  努力,努力再努力  阅读(905)  评论(0)    收藏  举报