先随便贴点代码
1、引用JwtBearer Nuget包
2、Program.cs启用JWT
using fly_chat1_net7.Middlewares;
using fly_chat1_net7.Middlewares.UserLoginAuthorizations;
using fly_webapi.IService.UserService.LoginAuthorization;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.CookiePolicy;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System;
using System.Net.Http;
using System.Text;
using System.Threading;
namespace fly_chat1_net7
{
public class Program
{
public static void Main(string[] args)
{
// try前也可能报错,但是错误是可控的。实际项目中使用时可以再加个try,只记录日志到文件中。
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) // 设置“configuration”的查找目录为程序目录
.AddJsonFile("appsettings.json") // 设置“configuration”的读取文件
.Build(); // 获取配置
var builder = WebApplication.CreateBuilder(args);
// 中间件知识https://learn.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/?view=aspnetcore-6.0#order
#region 容器Services
builder.Services.AddControllers(); // 添加Controller
builder.Services.AddHttpContextAccessor(); // 操作Http上下文;比如:AOP里面可以获取IOC对象
builder.Services.AddEndpointsApiExplorer(); // ASP.NET Core自身提供;Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
#region JWT
IUserAuthorization userAuthorization = new UserAuthorization_JWT();
builder.Services.AddSingleton(userAuthorization); // JWT认证中间件
builder.Services.AddAuthentication(options => {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options => { // 配置Authentication用的JWT
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidIssuer = configuration["Jwt:Issuer"],
ValidAudience = configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecurityKey"] ?? "a48fafeefd334237c2ca207e842afe0b")),
ClockSkew = TimeSpan.Zero
};
});
#endregion JWT
#endregion 容器Services
var app = builder.Build();
app.UseHttpsRedirection();
app.UseStaticFiles(); // 在UseRouting()前
app.UseRouting();
app.UseAuthentication(); // 认证
app.UseAuthorization(); // 授权
app.MapControllers();
app.Run();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
3、JWT的配置(appsettings.json中)
4、JWT登录认证中间件
using fly_webapi.IService.UserService.LoginAuthorization;
using fly_webapi.ViewModel.Users;
using Microsoft.Extensions.Primitives;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using System.Security.Claims;
using System.Text;
namespace fly_chat1_net7.Middlewares.UserLoginAuthorizations
{
/// <summary>
/// 用户认证_JWT
/// </summary>
public class UserAuthorization_JWT : IUserAuthorization
{
/// <summary>
/// 配置文件
/// </summary>
IConfigurationRoot _configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) // 设置“configuration”的查找目录为程序目录
.AddJsonFile("appsettings.json") // 设置“configuration”的读取文件
.Build(); // 获取配置
/// <summary>
/// 生成用户信息-创建Token
/// 从JWT中读取信息var name = HttpContext.User.FindFirst(JwtRegisteredClaimNames.Name)?.Value;
/// </summary>
/// <param name="userInfoVModel">用户信息</param>
public AuthorizationObject Create(UserInfoVModel userInfoVModel)
{
DateTime expiresAt = DateTime.UtcNow.AddMinutes(Convert.ToDouble(_configuration["Jwt:ExpireMinutes"])); // token 的过期时间
// 签发一个加密后的用户信息凭证ClaimsPrincipal,用来标识用户的身份
IEnumerable<Claim> claims = new Claim[] { // 将用户信息添加到 Claim 中
new Claim(ClaimTypes.Name,userInfoVModel.UserName), // 用户名
new Claim(ClaimTypes.Role,userInfoVModel.RoleId.ToString()), // 角色ID
new Claim(ClaimTypes.MobilePhone,userInfoVModel.MobilePhone), // 手机号
new Claim(ClaimTypes.Email,userInfoVModel.Email), // 邮箱号
new Claim(ClaimTypes.Expiration,expiresAt.ToString()) // 过期日期
};
//var identity = new ClaimsIdentity(claims, JwtBearerDefaults.AuthenticationScheme);
//_httpContextAccessor.HttpContext.SignInAsync(JwtBearerDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));
// 设置 SecurityTokenDescriptor
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecurityKey"] ?? "a48fafeefd334237c2ca207e842afe0b")); // 加密 token 的key值
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims), // 用户信息
Issuer = _configuration["Jwt:Issuer"], // Jwt token 的签发者
Audience = _configuration["Jwt:Audience"], // Jwt token 的接收者
Expires = expiresAt, // 过期时间
SigningCredentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256), //创建 token
};
JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor); // 创建Token
//存储 Token 信息
var jwt = new AuthorizationObject
{
//UserId = userInfoVModel.UserId, // 用户的Id
AuthorizationType=AuthorizationObjectType.Jwt_Microsoft, // AuthorizationObject类型为Jwt_Microsoft
Token = tokenHandler.WriteToken(token), // 获取创建完的Token
Expiration= expiresAt // 过期时间
};
// 把Token存放到MemoryCache或Redis中
return jwt;
}
/// <summary>
/// 停用Token
/// </summary>
/// <param name="token">Token</param>
/// <returns></returns>
public async Task<bool> DeactivateAsync(string token)
{
// 修改Token信息
// 把Token从MemoryCache或Redis中删除
return true;
}
/// <summary>
/// 停用当前Token
/// </summary>
/// <param name="token">Token</param>
/// <returns></returns>
public async Task<bool> DeactivateCurrentAsync(HttpContext httpContext) => await DeactivateAsync(GetCurrentAsync(httpContext));
/// <summary>
/// 刷新 Token
/// </summary>
/// <param name="token">Token</param>
/// <param name="dto">用户信息数据传输对象</param>
/// <returns></returns>
public async Task<AuthorizationObject> RefreshAsync(string token, UserInfoVModel userInfoVModel)
{
var jwtOld =await IsActiveAsync(token); // 判断 Token 是否有效
if (!jwtOld)
{
throw new Exception("未获取到当前用户信息!");
}
// 将旧的Token从MemoryCache或Redis中删除
var jwt = Create(userInfoVModel);
// 将新的Token存放到MemoryCache或Redis中
return jwt;
}
/// <summary>
/// 判断 Token 是否有效
/// </summary>
/// <param name="token">Token</param>
/// <returns></returns>
public async Task<bool> IsActiveAsync(string token)
{
// 检验1-Token是否有效(Token格式正常+未过期)
// 检验2-MemoryCache或Redis中是否存在(可以防伪造Token)
return true;
}
/// <summary>
/// 判断当前 Token 是否有效
/// </summary>
/// <returns></returns>
public async Task<bool> IsActiveCurrentAsync(HttpContext httpContext)=> await IsActiveAsync(GetCurrentAsync(httpContext));
#region private方法
/// <summary>
/// 获取 HTTP 请求的 Token 值
/// </summary>
/// <returns></returns>
private string GetCurrentAsync(HttpContext httpContext)
{
//http header
var authorizationHeader = httpContext.Request.Headers["authorization"];
//token
return authorizationHeader == StringValues.Empty? string.Empty: authorizationHeader.Single().Split(" ").Last(); // bearer tokenvalue
}
#endregion private方法
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
作者:꧁执笔小白꧂