2025-10-21 13:38:23 +08:00

96 lines
3.2 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Infrastructure;
using Infrastructure.Model;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System.Security.Claims;
using RIZO.Common;
namespace RIZO.ServiceCore.Middleware
{
/// <summary>
/// jwt认证中间件
/// </summary>
public class JwtAuthMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<JwtAuthMiddleware> _logger;
private static readonly string[] _whitelistPaths = new[]
{
".png",
"/msgHub"
};
public JwtAuthMiddleware(RequestDelegate next, ILogger<JwtAuthMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
var path = context.Request.Path.Value;
// 如果请求是带扩展名的(即包含 .
if (path.Contains('.'))
{
await _next(context);
return;
}
if (_whitelistPaths.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
{
await _next(context);
return;
}
var endpoint = context.GetEndpoint();
var allowAnonymous = endpoint?.Metadata?.GetMetadata<AllowAnonymousAttribute>() != null;
if (allowAnonymous)
{
await _next(context);
return;
}
string ip = HttpContextExtension.GetClientUserIp(context);
string url = context.Request.Path;
string osType = context.Request.Headers["os"];
TokenModel loginUser = JwtUtil.GetLoginUser(context);
if (loginUser != null)
{
var now = DateTime.UtcNow;
var ts = loginUser.ExpireTime - now;
var cacheKey = $"token_{loginUser.UserId}";
if (!CacheHelper.Exists(cacheKey) && ts.TotalMinutes < 5 && ts.TotalMinutes > 0)
{
var newToken = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser));
CacheHelper.SetCache(cacheKey, cacheKey, 1);
if (!string.IsNullOrEmpty(osType))
{
context.Response.Headers.Append("Access-Control-Expose-Headers", "X-Refresh-Token");
}
context.Response.Headers.Append("X-Refresh-Token", newToken);
_logger.LogInformation($"刷新Token: {loginUser.UserName}");
}
// 还可以挂载到 context.User
var identity = new ClaimsIdentity(JwtUtil.AddClaims(loginUser), "jwt");
context.User = new ClaimsPrincipal(identity);
await _next(context);
}
else
{
string msg = $"请求访问[{url}]失败Token无效或未登录";
_logger.LogWarning(msg);
//context.Response.StatusCode = StatusCodes.Status401Unauthorized;
await context.Response.WriteAsJsonAsync(ApiResult.Error(ResultCode.DENY, msg));
}
}
}
}