ASP .NET Core 8结合JWT轻松实现身份验证和授权

身份验证和授权是每一个后端服务必不可少的,可以实现对非法请求进行拦截,能够有效保护数据的安全性。

JSON Web Token(JWT)是一项开放标准(RFC 7519),它定义了一种紧凑且自包含的方法,用于以 JSON 对象的形式在各方之间安全地传递信息。这些信息经过数字签名,因此可以被验证和信任。

JWT官网文档:JSON Web Token Introduction - jwt.io

一、配置身份验证和授权

1、添加身份验证和JWT授权库

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

dotnet add package Microsoft.IdentityModel.Tokens

2、添加JWT配置信息到appsettings.json文件中

复制代码
"JwtTokenConfig": {
  "Secret": "T#cx^Q$qsd8UrJMnY1(Vz$iie~lA3jgB96drYoPP4IDOffds&Qrw6GG+HClJteU#$)^JzMN_it#o*WE+*qVhE(_Ryy_t)",
  "Issuer": "http://www.my.com/",
  "Audience": "http://www.my.com/",
  "AccessTokenExpiration": 240
}

3、创建JwtTokenConfig信息类

复制代码
public class JwtTokenConfig
{
    public string Secret { get; set; } = string.Empty;

    public string Issuer { get; set; } = string.Empty;

    public string Audience { get; set; } = string.Empty;

    public int AccessTokenExpiration { get; set; }
}

4、启用身份验证和JWT授权服务

复制代码
 var builder = WebApplication.CreateBuilder(args);

JwtTokenConfig? jwtTokenConfig = builder.Configuration.GetSection("JwtTokenConfig").Get<JwtTokenConfig>();
if (jwtTokenConfig != null)
{
    builder.Services.AddSingleton(jwtTokenConfig);
    builder.Services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = true;
        x.SaveToken = true;
        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidIssuer = jwtTokenConfig.Issuer,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(jwtTokenConfig.Secret)),
            ValidAudience = jwtTokenConfig.Audience,
            ValidateAudience = true,
            ValidateLifetime = true,
            ClockSkew = TimeSpan.FromMinutes(1)
        };
    });
}

var app = builder.Build();

5、显示注册身份验证和授权

复制代码
var app = builder.Build();

app.UseCors();
app.UseAuthentication();
app.UseAuthorization();

app.MapGet("/", () => "Hello World!");
app.Run();

注:身份验证中间件是在 CORS 中间件运行后运行的,所以需要显示注册身份验证和授权

6、在控制器基类中添加授权特性,对所有控制器施加授权验证

复制代码
[Route("api/[controller]/[action]")]
[ApiController]
[Authorize]
public abstract class BaseController : ControllerBase
{

}

二、生成JWT授权码

1、添加身份验证和JWT授权库

复制代码
dotnet add package System.IdentityModel.Tokens.Jwt

dotnet add package Microsoft.IdentityModel.Tokens

2、创建JWT授权服务接口

复制代码
public interface IJwtAuthService
{
    string GenerateJwtToken(Claim[] claims);
}

3、创建JWT授权服务业务逻辑

复制代码
public class JwtAuthService : IJwtAuthService
{
    private readonly JwtTokenConfig _jwtTokenConfig;

    public JwtAuthService(JwtTokenConfig jwtTokenConfig)
    {
        _jwtTokenConfig = jwtTokenConfig;
    }

    public string GenerateJwtToken(Claim[] claims)
    {
        bool shouldAddAudienceClaim = string.IsNullOrWhiteSpace(claims?.FirstOrDefault(x => x.Type == JwtRegisteredClaimNames.Aud)?.Value);
        JwtSecurityToken jwtToken = new(
            _jwtTokenConfig.Issuer,
            shouldAddAudienceClaim ? _jwtTokenConfig.Audience : string.Empty,
            claims,
            expires: DateTime.Now.AddMinutes(_jwtTokenConfig.AccessTokenExpiration),
            signingCredentials: new SigningCredentials(new SymmetricSecurityKey(_secret), SecurityAlgorithms.HmacSha256Signature));
        return new JwtSecurityTokenHandler().WriteToken(jwtToken);
        
    }
}

4、注册JWT授权服务

复制代码
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSingleton<IJwtAuthService, JwtAuthService>();

var app = builder.Build();

5、在授权控制器中使用JWT服务,生成Token

复制代码
public class AuthController : BaseController
{
    private readonly IJwtAuthService _authService;

    public AuthController(IAuthService authService)
    {
        _authService = authService;
    }

    [AllowAnonymous]
    [HttpPost]
    public IActionResult Login([FromBody] LoginRequest request)
    {
        // 1. 验证用户名密码(伪代码)
        if (!IsValidUser(request.User, request.Password))
            return Unauthorized();
        
        // 2. 创建JWT声明(伪代码)
        string roleName = "User";
        Claim[] claims =
        [
            new Claim(ClaimTypes.NameIdentifier, user),
            new Claim(ClaimTypes.Role, roleName)
        ];

        // 3. 生成 JWT Token
        var token = _authService.GenerateJwtToken(claims);

        // 4. 返回 Token
        return Ok(new { Token = token });
    }

    private bool IsValidUser(string user, string password)
    {
        // 实际应该查数据库(伪代码)
        return user == "admin" && password == "123456";
    }
}

注:使用ClaimTypes.NameIdentifier来声明用户标识,可以在集成SignalR时使SignalR很容易获取到用户标识并进行消息发送,因为SignalR默认获取的用户标识就是ClaimTypes.NameIdentifier

相关推荐
叫我阿柒啊6 天前
Java全栈开发面试实战:从基础到微服务的完整技术栈解析
java·spring boot·微服务·前端框架·vue·jwt·全栈开发
叫我阿柒啊7 天前
Java全栈开发实战:从基础到微服务的深度解析
java·微服务·kafka·vue3·springboot·jwt·前端开发
叫我阿柒啊14 天前
从Java全栈到前端框架:一场真实面试的深度技术探索
java·redis·微服务·typescript·vue3·springboot·jwt
叫我阿柒啊14 天前
从Java全栈到前端框架:一场真实的技术面试实录
java·spring boot·redis·typescript·vue3·jwt·前后端分离
csdn_aspnet14 天前
.NET 8 集成 JWT Bearer Token
jwt·.net8
༒࿈༙྇洞察༙༙྇྇࿈༒19 天前
jwt原理及Java中实现
java·开发语言·状态模式·jwt
3Cloudream20 天前
互联网大厂Java面试实录:Spring Boot与微服务架构解析
spring boot·微服务·hibernate·jwt·java面试
叫我阿柒啊22 天前
从全栈开发到微服务架构:一次真实的Java面试实录
java·redis·ci/cd·微服务·vue3·springboot·jwt
Mysticbinary1 个月前
JWT身份认证原理介绍
鉴权·jwt·签名·会话认证
小李是个程序1 个月前
登录与登录校验:Web安全核心解析
java·spring·web安全·jwt·cookie