装修公司网站模板,养老服务业扶持政策,ps网页设计案例,自己的网站怎么接广告在当今的软件开发中#xff0c;安全性和用户认证是至关重要的方面。JSON Web Token#xff08;JWT#xff09;作为一种流行的身份验证机制#xff0c;因其简洁性和无状态特性而被广泛应用于各种应用中#xff0c;尤其是在 ASP.NET Core 项目里。本文将详细介绍如何在 ASP.…在当今的软件开发中安全性和用户认证是至关重要的方面。JSON Web TokenJWT作为一种流行的身份验证机制因其简洁性和无状态特性而被广泛应用于各种应用中尤其是在 ASP.NET Core 项目里。本文将详细介绍如何在 ASP.NET Core 应用中实现 JWT 鉴权确保应用能够安全地验证用户身份并授权访问特定资源。
一、安装必要的 NuGet 包
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
这个包提供了 JWT 身份验证所需的所有功能包括对 JWT 令牌的解析和验证。
二、配置 JWT 身份验证
在应用的配置文件 appsettings.json 中添加 JWT 相关的配置信息。这些配置包括密钥、发行者、受众和令牌的有效期等
{JwtSettings: {Secret: YourSecretKeyYourSecretKeyYourSecretKeyYourSecretKey, // 用于加密的密钥应非常复杂Issuer: YourAppName, // 发行者Audience: YourAppUsers, // 受众ExpireMinutes: 120 // 令牌有效期}
}
在 Program.cs 文件中需要配置 JWT 认证方案以便 ASP.NET Core 知道如何处理 JWT 令牌
var builder WebApplication.CreateBuilder(args);var jwtSettings builder.Configuration.GetSection(JwtSettings);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 jwtSettings[Issuer],ValidAudience jwtSettings[Audience],IssuerSigningKey new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings[Secret])),ClockSkew TimeSpan.Zero // 默认的 5 分钟偏移时间};options.Events new JwtBearerEvents
{ OnMessageReceived context {var token context.Request.Headers[Authorization].ToString()?.Replace(Bearer , );if (!string.IsNullOrEmpty(token)){context.Token token;}return Task.CompletedTask;},OnAuthenticationFailed context {// 如果过期把过期信息添加到头部if (context.Exception.GetType() typeof(SecurityTokenExpiredException)){context.Response.Headers.Append(Token-Expired, true);}return Task.CompletedTask;}
};
});var app builder.Build();
app.UseAuthentication();
app.UseAuthorization();
配置了 JWT 身份验证的中间件确保所有传入的请求都会被检查是否包含有效的 JWT 令牌。
JwtBearerEvents的订阅事件 // 1. **OnMessageReceived**:// -触发时机当接收到一个身份验证请求。// -用途用来处理接收到的原始身份验证消息可以根据请求的具体情况来修改或取消身份验证过程。//2. * *OnTokenValidated * *:// -触发时机在JWT被成功验证后触发。// -用途用来处理已验证的token例如可以在这里添加额外的日志记录或执行一些安全检查。//3. * *OnAuthenticationFailed * *:// -触发时机当身份验证失败时触发。// -用途用来处理身份验证失败的情况例如记录失败原因、执行额外的错误处理逻辑等。//4. * *OnChallenge * *:// -触发时机当需要向客户端发出一个挑战例如要求客户端提供凭据时触发。// -用途自定义挑战的响应例如修改返回给客户端的401 Unauthorized响应。//5. * *OnForbidden * *:// -触发时机当授权失败时触发即用户已通过身份验证但没有足够的权限访问特定资源。// -用途自定义处理禁止访问的情况例如返回一个自定义的错误消息或执行其他逻辑。
三、生成 JWT Token
为了使用户能够登录并获取 JWT 令牌需要创建一个控制器或服务来处理登录请求并生成 JWT 令牌。以下是一个简单的登录 API 示例
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;[ApiController]
[Route(api/[controller])]
publicclassAuthController : ControllerBase
{privatereadonly IConfiguration _configuration;public AuthController(IConfiguration configuration){_configuration configuration;}[HttpPost(login)]public IActionResult Login([FromBody] LoginRequest loginRequest){// 假设已经验证了用户名和密码if (loginRequest.Username admin loginRequest.Password password){var token GenerateJwtToken(loginRequest.Username);return Ok(new { token });}return Unauthorized();}private string GenerateJwtToken(string username){var jwtSettings _configuration.GetSection(JwtSettings);var claims new[]{new Claim(JwtRegisteredClaimNames.Sub, username),new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())//添加更多的标识};var key new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings[Secret]));var creds new SigningCredentials(key, SecurityAlgorithms.HmacSha256);var token new JwtSecurityToken(issuer: jwtSettings[Issuer],audience: jwtSettings[Audience],claims: claims,expires: DateTime.Now.AddMinutes(double.Parse(jwtSettings[ExpireMinutes])),signingCredentials: creds);returnnew JwtSecurityTokenHandler().WriteToken(token);}
}publicclassLoginRequest
{publicstring Username { get; set; }publicstring Password { get; set; }
}
四、保护 API 路由
一旦有了 JWT 令牌生成机制接下来需要保护 API 路由确保只有携带有效 JWT 令牌的请求可以访问受保护的资源。
可以通过在控制器或操作方法上使用 [Authorize] 特性来实现
[AllowAnonymous]可跳过授权
[ApiController]
[Route([controller])]
[Authorize]
publicclassWeatherForecastController : ControllerBase
{[Authorize][HttpGet(Name GetWeatherForecast)]public IEnumerableWeatherForecast Get(){return Enumerable.Range(1, 5).Select(index new WeatherForecast{Date DateOnly.FromDateTime(DateTime.Now.AddDays(index)),TemperatureC Random.Shared.Next(-20, 55),Summary Summaries[Random.Shared.Next(Summaries.Length)]}).ToArray();}
}
五、客户端请求
客户端在请求受保护的 API 时必须在请求头中添加 Authorization 字段格式为 Bearer token
GET /api/protected/data HTTP/1.1
Host: yourdomain.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
这样服务器就能通过 JWT 中间件验证令牌的有效性并允许或拒绝请求。
六、扩展Swagger集成传递验证 需要使用包Swashbuckle.AspNetCore builder.Services.AddSwaggerGen(options options.SwaggerTokenConfigure());
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI();
}
SwaggerConfiguration将token保存到swagger并传递到后台
public staticclassSwaggerConfiguration
{public static void SwaggerTokenConfigure(this SwaggerGenOptions options){options.SwaggerDoc(v1, new OpenApiInfo{Title JWT Auth API,Version v1,Description A sample API for JWT Authentication});options.AddSecurityDefinition(Bearer, new OpenApiSecurityScheme{Description JWT Authorization header using the Bearer scheme.,Name Authorization,In ParameterLocation.Header,Type SecuritySchemeType.Http,Scheme Bearer,BearerFormat JWT});options.AddSecurityRequirement(new OpenApiSecurityRequirement{{new OpenApiSecurityScheme{Reference new OpenApiReference{Type ReferenceType.SecurityScheme,Id Bearer}},Array.Emptystring()}});}
}有关swagger更多的详细配置请参考 https://mp.weixin.qq.com/s/Xke2EyUHuxR_RdHbSXP5Ew
分组https://mp.weixin.qq.com/s/Ut9leANrq4pJMgOQFmVkqg
七、扩展获取身份验证信息
老规矩先注册
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingletonIHttpContextAccessor, HttpContextAccessor();
builder.Services.AddTransientIAppUser, AppUser();存放用户信息的接口和实现类 public interfaceIAppUser{string Username { get; }string HeaderToken { get; }}publicclassAppUser : IAppUser{privatereadonly HttpContext _httpContext;public AppUser(IHttpContextAccessor httpContextAccessor){_httpContext httpContextAccessor?.HttpContext;}publicstring Username { get _httpContext?.User.Claims.FirstOrDefault(s s.Type Username)?.Value.ToString()??; }publicstring HeaderToken{get{if (_httpContext.Request.Headers.ContainsKey(Authorization)){return _httpContext?.Request.Headers[Authorization].ToString().Replace(Bearer , ).Trim();}returnstring.Empty;}}}
直接使用 private readonly IAppUser _appUser ;public AuthController(IConfiguration configuration, IAppUser appUser){_configuration configuration;_appUserappUser;}[HttpGet]public IActionResult Getuserinfo(){return Ok(new { _appUser.Username, _appUser.HeaderToken });}可以成功获取到用户存放的token信息不过现在还有一个弊端就是每次都需要构造注入才可以过去用户信息是比较麻烦的其实我们可以通过封装一下将AppUser存放到App全局配置里面直接静态获取这样在需要获取用户信息的时候就不需要每次都构造注入了 等后面有机会出优化和封装教程或者直接参考https://gitee.com/Pridejoy/MalusAdmin
八、可选角色授权
如果应用需要基于角色进行授权可以在生成 JWT 令牌时添加角色信息
private string GenerateJwtToken(string username)
{var claims new[]{new Claim(JwtRegisteredClaimNames.Sub, username),new Claim(ClaimTypes.Role, Admin), // 添加角色new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())};// 剩余代码与前面一致
}
然后可以使用 [Authorize(Roles Admin)] 特性来限定只有特定角色的用户才能访问
[Authorize(Roles Admin)]
[HttpGet(admin-data)]
public IActionResult GetAdminData()
{return Ok(new { message This is admin data });
}
总结
通过以上操作就可以在 ASP.NET Core 应用中实现 JWT 鉴权确保你的应用能够安全地验证用户身份并授权访问特定资源。JWT 的无状态特性和灵活性使其成为现代 Web 应用中身份验证的理想选择。