96 lines
3.2 KiB
C#
96 lines
3.2 KiB
C#
|
|
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));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|