ASP.NET Web API自定义中间件顺序不生效问题求助
问题分析
- 从日志和代码能看出,普通用户登录请求
/api/user/login触发了AdminMiddleware执行,但后续请求没有流转到JWT中间件和控制器。核心原因是AdminMiddleware仅处理/admin开头的路径,非/admin路径下没有调用await next(context),导致请求被直接终止,无法到达登录接口。 - 你看到的AdminMiddleware先执行的现象,本质是请求卡在了AdminMiddleware,JWT中间件根本没机会运行,并非注册顺序导致的执行顺序颠倒。
解决方案
1. 修复AdminMiddleware的请求流转逻辑
修改AdminMiddleware的InvokeAsync方法,在非/admin路径下明确调用await next(context),确保请求能继续向后传递到JWT中间件和控制器:
namespace E_Commerce_BackEnd.MIddleware; public class AdminMiddleware : IMiddleware { private readonly ILogger<AdminMiddleware> _logger; public AdminMiddleware(ILogger<AdminMiddleware> logger) { _logger = logger; } public async Task InvokeAsync(HttpContext context, RequestDelegate next) { try { _logger.LogInformation("Executin admin middleware"); var path = context.Request.Path; _logger.LogInformation(path.ToString()); bool isLoggedInBool = context.Request.Cookies.TryGetValue("userLoggedIn", out var isLoggedInString); if (path.StartsWithSegments("/admin")) { var isAdmin = false; if (path.StartsWithSegments("/admin/login")) { _logger.LogInformation("Entering admin/login endpoint"); if (isLoggedInBool && isLoggedInString == "1" && context.Request.Cookies.TryGetValue("admin", out var adminLogInCheck)) { if (adminLogInCheck == "1") { isAdmin = true; await next(context); return; } context.Response.StatusCode = StatusCodes.Status401Unauthorized; _logger.LogWarning($"Non-admin tried to acces -> {path}"); await context.Response.WriteAsync("You are not allowed here!"); } } if (isLoggedInBool && isLoggedInString == "1" && context.Request.Cookies.TryGetValue("admin", out var admin)) { _logger.LogInformation("Entering /admin/* endpoint"); bool adminIsLoggedIn = context.Request.Cookies.TryGetValue("adminLoggedIn", out var adminLoggedInString); if (admin == "1" && adminIsLoggedIn && adminLoggedInString == "1" ) { isAdmin = true; await next(context); return; } context.Response.StatusCode = StatusCodes.Status401Unauthorized; _logger.LogWarning($"Non-admin tried to acces/ Or invalid validation for the adminLoggedIn cookie -> {path}"); await context.Response.WriteAsync("You are not allowed here!"); return; } else { context.Response.StatusCode = StatusCodes.Status401Unauthorized; if (!isLoggedInBool) { _logger.LogWarning("User is not logged in (middleware)"); await context.Response.WriteAsync("User is not logged in"); return; }else if (isLoggedInBool && !isAdmin) { _logger.LogWarning($"Admin cookie not present! Path that was tried -> {path}"); await context.Response.WriteAsync("Admin cookie not present"); return; } } await next(context); } else { // 非/admin路径,直接传递请求到下一个中间件 await next(context); } } catch (Exception e) { _logger.LogError("Error in the admin middleware"); _logger.LogInformation(e.Message); throw; } } }
2. 确认中间件注册顺序合理性
你当前Program.cs中的注册顺序是正确的:先注册JWT校验中间件,再注册Admin权限控制中间件,确保JWT身份校验先执行,之后再做Admin权限判断。修复AdminMiddleware逻辑后,这个顺序会正常生效。
3. 验证登录流程
修复完成后,普通用户登录请求/api/user/login会先经过JWT中间件(因为登录接口应该标记了[AllowAnonymous],JWT中间件会直接放行到控制器),控制器处理登录逻辑并设置JWT Token和userLoggedInCookie,后续请求就能正常通过JWT校验。
内容的提问来源于stack exchange,提问作者Misu Stefan
相关产品推荐
相关产品推荐

