diff --git a/Attributes/SimApiAuthAttribute.cs b/Attributes/SimApiAuthAttribute.cs index 2c66aaf..3565f7f 100644 --- a/Attributes/SimApiAuthAttribute.cs +++ b/Attributes/SimApiAuthAttribute.cs @@ -1,9 +1,11 @@ using System; using System.Linq; -using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.DependencyInjection; using SimApi.Communications; using SimApi.Exceptions; +using SimApi.Interfaces; +using static SimApi.Helpers.SimApiError; namespace SimApi.Attributes; @@ -37,17 +39,16 @@ public class SimApiAuthAttribute : ActionFilterAttribute public override void OnActionExecuting(ActionExecutingContext context) { var loginInfo = (SimApiLoginItem)context.HttpContext.Items["LoginInfo"]!; - //检测是否登录 - if (loginInfo == null) + var token = (string)context.HttpContext.Items["LoginToken"]!; + ErrorWhenNull(loginInfo, 401); + var checkers = context.HttpContext.RequestServices.GetServices(); + foreach (var checker in checkers) { - throw new SimApiException(401); + checker.Run(loginInfo, token); } if (Types == null) return; //检测用户类型 - if (!Types.Intersect(loginInfo.Type).Any()) - { - throw new SimApiException(403); - } + ErrorWhenFalse(Types.Intersect(loginInfo.Type).Any(), 403); } } \ No newline at end of file diff --git a/Controllers/SimApiAuthController.cs b/Controllers/SimApiAuthController.cs index e6e7234..e13f563 100644 --- a/Controllers/SimApiAuthController.cs +++ b/Controllers/SimApiAuthController.cs @@ -10,15 +10,11 @@ using static SimApiError; public class SimApiAuthController(SimApiAuth auth) : SimApiBaseController { /// - /// 检测用户登陆的控制器 + /// 获取已登录用户信息 /// /// - [HttpPost, SimApiDoc("认证", "检测登陆")] - public string CheckLogin() - { - ErrorWhenNull(LoginInfo, 401, "未登录"); - return LoginInfo.Id; - } + [HttpPost, SimApiAuth, SimApiDoc("认证", "获取已登录用户信息")] + public SimApiLoginItem UserInfo() => LoginInfo; /// /// 退出登陆 @@ -32,8 +28,4 @@ public class SimApiAuthController(SimApiAuth auth) : SimApiBaseController auth.Logout(value!); } } - - - [HttpPost, SimApiAuth, SimApiDoc("认证", "获取已登录用户信息")] - public SimApiLoginItem UserInfo() => LoginInfo; } \ No newline at end of file diff --git a/Controllers/SimApiBaseController.cs b/Controllers/SimApiBaseController.cs index 70bc9d8..b7653a5 100644 --- a/Controllers/SimApiBaseController.cs +++ b/Controllers/SimApiBaseController.cs @@ -23,7 +23,7 @@ public class SimApiBaseController : Controller /// protected SimApiLoginItem LoginInfo => (SimApiLoginItem)HttpContext.Items["LoginInfo"]!; - protected SimApiLoginItem LoginToken => (SimApiLoginItem)HttpContext.Items["LoginToken"]!; + protected string LoginToken => (string)HttpContext.Items["LoginToken"]!; /// /// 验证请求参数 diff --git a/Controllers/SimApiCommonController.cs b/Controllers/SimApiCommonController.cs index aa0df92..92bcc41 100644 --- a/Controllers/SimApiCommonController.cs +++ b/Controllers/SimApiCommonController.cs @@ -1,6 +1,8 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; +using SimApi.Attributes; using SimApi.Helpers; +using static SimApi.Helpers.SimApiError; namespace SimApi.Controllers; @@ -28,4 +30,15 @@ public class SimApiCommonController : SimApiBaseController { "App", SimApiUtil.AppVersion } }; } + + /// + /// 检测用户登陆的控制器 + /// + /// + [HttpPost, SimApiAuth, SimApiDoc("认证", "检测登陆")] + public string CheckLogin() + { + ErrorWhenNull(LoginInfo, 401, "未登录"); + return LoginInfo.Id; + } } \ No newline at end of file diff --git a/Helpers/SimApiAuth.cs b/Helpers/SimApiAuth.cs index dfc44b5..46a8f9d 100644 --- a/Helpers/SimApiAuth.cs +++ b/Helpers/SimApiAuth.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Text.Json; using Microsoft.Extensions.Caching.Distributed; using SimApi.Communications; using StackExchange.Redis; @@ -137,8 +136,9 @@ public class SimApiAuth(IDistributedCache cache, IConnectionMultiplexer redis) { var setCacheKey = TokenSetCacheKey.Replace("{userId}", item.Id); _redisDb.SetRemove(setCacheKey, token); - var cacheKey = TokenCacheKey.Replace("{token}", token); - cache.Remove(cacheKey); } + + var cacheKey = TokenCacheKey.Replace("{token}", token); + cache.Remove(cacheKey); } } \ No newline at end of file diff --git a/Interfaces/ISimApiAuthChecker.cs b/Interfaces/ISimApiAuthChecker.cs new file mode 100644 index 0000000..afefd64 --- /dev/null +++ b/Interfaces/ISimApiAuthChecker.cs @@ -0,0 +1,8 @@ +using SimApi.Communications; + +namespace SimApi.Interfaces; + +public interface ISimApiAuthChecker +{ + public void Run(SimApiLoginItem loginItem, string token); +} \ No newline at end of file diff --git a/Middlewares/SimApiAuthMiddleware.cs b/Middlewares/SimApiAuthMiddleware.cs index daac6d1..4b00084 100644 --- a/Middlewares/SimApiAuthMiddleware.cs +++ b/Middlewares/SimApiAuthMiddleware.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using SimApi.Helpers; @@ -11,11 +12,9 @@ public class SimApiAuthMiddleware(RequestDelegate next) { public Task Invoke(HttpContext httpContext, SimApiAuth auth) { - string? token = null; - if (httpContext.Request.Headers.TryGetValue("Token", out var header)) - { - token = header; - } + var token = + httpContext.Request.Headers["Token"].FirstOrDefault() + ?? httpContext.Request.Query["token"].FirstOrDefault(); if (string.IsNullOrEmpty(token)) return next(httpContext); var login = auth.GetLogin(token); diff --git a/SimApiExtensions.cs b/SimApiExtensions.cs index 6fdabd7..8f3bc3b 100644 --- a/SimApiExtensions.cs +++ b/SimApiExtensions.cs @@ -18,6 +18,7 @@ using Microsoft.Extensions.Logging; using SimApi.Attributes; using SimApi.CoceSdk; using SimApi.Configurations; +using SimApi.Interfaces; using SimApi.Logger; using SimApi.SwaggerFilters; using StackExchange.Redis; @@ -63,6 +64,20 @@ public static class SimApiExtensions builder.AddSingleton(); } + var simApiAuthChecker = typeof(ISimApiAuthChecker); + var stackTrace = new StackTrace(); + var callingMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1)?.GetMethod(); + var callerAssembly = callingMethod?.DeclaringType?.Assembly; + var callerTypes = callerAssembly?.GetTypes() ?? []; + + foreach (var type in callerTypes) + { + if (type is { IsClass: true, IsAbstract: false } && simApiAuthChecker.IsAssignableFrom(type)) + { + builder.AddScoped(simApiAuthChecker, type); + } + } + if (simApiOptions.EnableJob) { builder.AddHangfire(x => @@ -96,12 +111,7 @@ public static class SimApiExtensions if (simApiOptions.EnableSynapse) { builder.AddSingleton(); - //自动依赖注入 - var stackTrace = new StackTrace(); - var callingMethod = stackTrace.GetFrame(stackTrace.FrameCount - 1)?.GetMethod(); - var assembly = callingMethod?.DeclaringType?.Assembly; - var types = assembly?.GetTypes() ?? []; - foreach (var type in types) + foreach (var type in callerTypes) { var methodsWithSynapse = type.GetMethods() .Where(m => m.GetCustomAttribute() != null || @@ -394,6 +404,14 @@ public static class SimApiExtensions builder.MapControllers(); } + var checkers = builder.Services.CreateScope().ServiceProvider.GetServices().ToArray(); + if (checkers.Length != 0) + { + var msg = checkers.Aggregate("开始配置SimApiAuthChecker...", + (current, checker) => current + $"\n|- {checker.GetType().FullName}"); + logger.LogInformation(msg); + } + if (options.EnableSimApiGateAuth) { logger.LogInformation("开始配置SimApiGateAuth..."); @@ -408,6 +426,12 @@ public static class SimApiExtensions } } + builder.MapControllerRoute(name: "CheckLogin", pattern: "/auth/check", + defaults: new + { + controller = "SimApiCommon", + action = "CheckLogin" + }); if (options.EnableSimApiAuth) { logger.LogInformation("开始配置SimApiAuth..."); @@ -418,12 +442,7 @@ public static class SimApiExtensions controller = "SimApiAuth", action = "UserInfo" }); - builder.MapControllerRoute(name: "CheckLogin", pattern: "/auth/check", - defaults: new - { - controller = "SimApiAuth", - action = "CheckLogin" - }); + builder.MapControllerRoute(name: "Logout", pattern: "/auth/logout", defaults: new {