JWT授权配置
1、 安装Microsoft.IdentityModel.Tokens包;
2、 创建一个认证用户信息实体类UserInfo
3、 创建一个JWT配置类 JWTTokenOptions
public class JwtTokenOptions
{
/// <summary>
/// JWT 认证Key
/// </summary>
public string SecurityKey { get; set; }
/// <summary>
/// token 过期时间,单位为小时
/// </summary>
public int Expire { get; set; }
/// <summary>
/// 接受者受众者
/// </summary>
public string Audience { get; set; }
/// <summary>
/// 发行者
/// </summary>
public string Issuer { get; set; }
}
4、 在appsettings.json 配置文件添加 JWT Token 配置信息
"JwtTokenOptions": {
"SecurityKey": "xxxeegwawegghtop6!@#$%%^", //用于生成token的秘钥 至少16位此处24位,可输入任意字符
"Expire": "2", //单位小时
"Audience": "",
"Issuer": ""
}
5、 创建Jwt管理接口用于创建Token
public interface IAuthManage
{
/// <summary>
/// 生成JwtToken
/// </summary>
/// <param name="userInfo"></param>
/// <returns></returns>
string GenrateJwtToken(UserInfo userInfo);
}
6、 创建Jwt管理接口实现类用于创建Token
using IPSP.DTO.Auth;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
namespace IPSP.Common.Auth
{
//用于生成token的实现类
public class JwtAuthManage : IAuthManage
{
private readonly JwtTokenOptions _jwtTokenOptions;
public JwtAuthManage(JwtTokenOptions jwtTokenOptions)
{
_jwtTokenOptions = jwtTokenOptions;
}
public string GenrateJwtToken(UserInfo userInfo)
{
string hours = _jwtTokenOptions.Expire.ToString();
var tokenHandler = new JwtSecurityTokenHandler();
//获取用于生成Token的key
var key = Encoding.ASCII.GetBytes(_jwtTokenOptions.SecurityKey);
var tokenDescriptor = new SecurityTokenDescriptor
{
//获取或者设置身份信息
Subject = new System.Security.Claims.ClaimsIdentity(new Claim[] {
new Claim("userInfo", JsonSerializer.Serialize(userInfo))
}),
//设置过期时间
Expires = DateTime.UtcNow.AddHours(_jwtTokenOptions.Expire),
//证书签名
SigningCredentials = new SigningCredentials(
new SymmetricSecurityKey(key),
SecurityAlgorithms.HmacSha256Signature
)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
}
7、 创建JWT 中间件JwtMiddleware 用于验证Token
using IPSP.BLL.IService.SystemManage;
using IPSP.Common.Auth;
using IPSP.DTO.Auth;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Text.Json;
namespace IPSP.Middlewares
{
public static class JwtMiddlewareExtension
{
public static IApplicationBuilder UseJwtMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<JwtMiddleware>();
}
}
public class JwtMiddleware
{
private readonly RequestDelegate _next;
private readonly JwtTokenOptions _jwtTokenOptions;
public JwtMiddleware(RequestDelegate next, JwtTokenOptions jwtTokenOptions)
{
_next = next;
_jwtTokenOptions = jwtTokenOptions;
}
public async Task InvokeAsync(HttpContext context)
{
//从上下文提取token
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (token != null)
{
}
//调用下一个中间件
await _next(context);
}
public void AttacheUserToContext(HttpContext context,IUserService userService,string? token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
//用于生产token
var key = Encoding.ASCII.GetBytes(_jwtTokenOptions.SecurityKey);
tokenHandler.ValidateToken(token, new Microsoft.IdentityModel.Tokens.TokenValidationParameters
{
ValidateIssuerSigningKey = true,//是否验证key SecurityKey
IssuerSigningKey = new SymmetricSecurityKey(key),//获取SecurityKey
ValidateIssuer = false,//是否验证Issuer
ValidateAudience = false,//是否验证Audience
ValidateLifetime = true,//是否验证Token的失效时间
},out SecurityToken validateToken);
var jwtToken = (JwtSecurityToken)validateToken;
//获取Token
var userInfo = jwtToken.Claims.First(x=>x.Type == "userInfo").Value;
var userModel = JsonSerializer.Deserialize<UserInfo>(userInfo);
//写入认证信息,方便业务类使用
var claimsIdentity = new ClaimsIdentity(new Claim[] {
new Claim("userInfo",jwtToken.Claims.First(x=>x.Type == "userInfo").Value)
});
Thread.CurrentPrincipal = new ClaimsPrincipal(claimsIdentity);
//将Token中解析出来的用户信息存入当前请求中
context.Items["UserInfo"] = userModel;
}
catch (Exception)
{
context.Items["UserInfo"] = null;
}
}
}
}
8、 创建自定义全局权限认证过滤器
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
namespace IPSP.Common.Auth
{
/// <summary>
/// 鉴权、身份认证授权的过滤器
/// </summary>
public class CustomAuthorizeAttribute : IAuthorizationFilter
{
public void OnAuthorization(AuthorizationFilterContext context)
{
var user = context.HttpContext.Items["UserInfo"];
//验证是否需要授权和授权信息
if (HasAllowAnonymous(context) == false && user == null)
{
context.Result = new JsonResult(new { message = "Token验证失败或已过期请重新登录并获取!!" })
{
StatusCode = StatusCodes.Status401Unauthorized
};
}
}
private static bool HasAllowAnonymous(AuthorizationFilterContext context)
{
var filters = context.Filters;
if (filters.OfType<IAllowAnonymousFilter>().Any())
{
return true;
}
var endpoint = context.HttpContext.GetEndpoint();
return endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null;
}
}
}
9、 在Program.cs 文件中读取JWT配置,并将JWT配置对象 jwtTokenOptions,JwtAuthManage依赖注入
var builder = WebApplication.CreateBuilder(args);
//读取配置文件中的JwtTokenOptions字段
builder.Services.Configure<JwtTokenOptions>(builder.Configuration.GetSection("JwtTokenOptions"));
//将字段中的值赋值给JwtTokenOptions 类
JwtTokenOptions tokenOptions = new JwtTokenOptions();
builder.Configuration.Bind("JwtTokenOptions",tokenOptions);
#region IOC
// Add services to the container.
//依赖注入 将配置注入
builder.Services.AddSingleton(tokenOptions);
builder.Services.AddSingleton<IAuthManage>(new JwtAuthManage(tokenOptions));
10、在Program.cs 文件中启用JWT中间件 JwtMiddleware
//在授权前调用验证token中间件
app.UseJwtMiddleware();
app.UseAuthorization();
注意:在授权前调用验证token中间件
11、使用token
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
private IUserService _userservice;
private readonly ILogger<LoginController> _logger;
private readonly IAuthManage _authManage;
private readonly JwtTokenOptions _jwtTokenOptions;
public LoginController(IUserService userService,ILogger<LoginController> logger,IAuthManage authManage,IOptionsMonitor<JwtTokenOptions> jwtTokenOptions) {
_userservice= userService;
_logger = logger;
_authManage= authManage;
_jwtTokenOptions = jwtTokenOptions.CurrentValue;
}
[HttpGet]
public async Task<IActionResult> UserLogin([FromQuery]LoginModel model)
{
User user = new User();
user.Badge = model.Badge;
user.Password = model.Password;
UserInfo userInfo = await _userservice.Login(user.Badge,user.Password);
if (userInfo != null)
{
string token = _authManage.GenrateJwtToken(userInfo);//生成token
_logger.LogInformation($"{userInfo.Badge}-{userInfo.CName}在{DateTime.Now.ToString("yyyy-dd-MM HH:mm:ss")}登入了IPSP系统!");
var result = new
{
user= userInfo,
token=token
};
return Ok(result);
}
return Ok(userInfo);
}
}
标签:Core,jwtTokenOptions,自定义,JWT,token,userInfo,using,new,public From: https://www.cnblogs.com/xjxue/p/17590766.html