2025-02-24 09:50:17 +00:00
|
|
|
|
using Microsoft.AspNetCore.Authorization;
|
|
|
|
|
using HttpContext = Microsoft.AspNetCore.Http.HttpContext;
|
|
|
|
|
|
|
|
|
|
namespace ZhiYi.Core.Application.Middleware
|
2025-02-21 01:14:39 +00:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 签名与鉴权中间件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class SignatureValidationMiddleware
|
|
|
|
|
{
|
|
|
|
|
private readonly RequestDelegate _next;
|
|
|
|
|
private readonly string _appSecret;
|
|
|
|
|
private readonly string[] _excludedPaths;
|
|
|
|
|
private readonly IServiceProvider _serviceProvider;
|
|
|
|
|
|
|
|
|
|
public SignatureValidationMiddleware(RequestDelegate next, IConfiguration configuration, IServiceProvider serviceProvider)
|
|
|
|
|
{
|
|
|
|
|
_next = next;
|
|
|
|
|
_appSecret = configuration["AppSecret"];
|
|
|
|
|
_excludedPaths = new string[]
|
|
|
|
|
{
|
|
|
|
|
"/api/user/login", // 登录接口
|
|
|
|
|
"/api/user/register", // 注册接口
|
|
|
|
|
"/api/user/getsignature", //签名获取接口
|
|
|
|
|
"/api/captcha/getcaptcha" //验证码获取接口
|
|
|
|
|
};
|
|
|
|
|
_serviceProvider = serviceProvider;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-24 09:50:17 +00:00
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
2025-02-21 01:14:39 +00:00
|
|
|
|
{
|
|
|
|
|
/*var contentType = context.Request.ContentType;
|
|
|
|
|
if (contentType.IndexOf("grpc") > 0)
|
|
|
|
|
{
|
|
|
|
|
await _next(context);
|
|
|
|
|
return;
|
|
|
|
|
}*/
|
2025-02-24 09:50:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var endpoint = context.GetEndpoint();
|
|
|
|
|
if (endpoint?.Metadata.GetMetadata<AllowAnonymousAttribute>() != null)
|
|
|
|
|
{
|
|
|
|
|
// 如果标记了 [AllowAnonymous] 特性,则跳过中间件认证过程
|
|
|
|
|
await _next(context);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2025-02-21 01:14:39 +00:00
|
|
|
|
var path = context.Request.Path;
|
|
|
|
|
if (_excludedPaths.Any(p => path.StartsWithSegments(p)))
|
|
|
|
|
{
|
|
|
|
|
await _next(context);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
var timestamp = context.Request.Headers["X-Timestamp"].ToString();
|
|
|
|
|
var token = context.Request.Headers["Authorization"].ToString().Replace("Bearer ", "");
|
|
|
|
|
var signature = context.Request.Headers["X-Signature"].ToString();
|
|
|
|
|
|
|
|
|
|
//请求头过滤
|
|
|
|
|
/*if (string.IsNullOrEmpty(timestamp) || string.IsNullOrEmpty(token) || string.IsNullOrEmpty(signature))
|
|
|
|
|
{
|
|
|
|
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
|
|
|
await context.Response.WriteAsync("非法请求");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 简单验证 signature 是否有效
|
|
|
|
|
using (var scope = _serviceProvider.CreateScope())
|
|
|
|
|
{
|
|
|
|
|
var expectedSignature = scope.ServiceProvider.GetService<TokenService>().GenerateSignature(_appSecret, path, timestamp, token);
|
|
|
|
|
if (signature != expectedSignature)
|
|
|
|
|
{
|
|
|
|
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
|
|
|
await context.Response.WriteAsync("签名不正确");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
};*/
|
|
|
|
|
|
|
|
|
|
// 简单验证 Token 是否有效
|
|
|
|
|
var tokenService = context.RequestServices.GetRequiredService<TokenService>();
|
|
|
|
|
var username = context.User.Identity?.Name;
|
|
|
|
|
var userid = context.User.FindFirst(ClaimTypes.Sid)?.Value;
|
|
|
|
|
if (userid == null || !tokenService.ValidateToken(userid, token))
|
|
|
|
|
{
|
|
|
|
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
|
|
|
|
await context.Response.WriteAsync("token无效");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await _next(context);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|