ASP.NET Core MVC未授权请求返回405却显示404问题排查
核心原因
过滤器的Result被无条件覆盖
你的HandleUnauthorizedRequest方法中,即使判断是Ajax请求并设置了StatusCodeResult,后续代码没有添加else分支,会无条件执行重定向逻辑,直接覆盖之前设置的状态码Result。最终不管是否为Ajax请求,都会尝试跳转到Home/Index。目标重定向路由不存在
Program.cs里的默认路由指向Login/Index,如果项目中没有HomeController或其Index方法未实现,重定向请求会找不到对应资源,返回404。状态码中间件的间接影响
UseStatusCodePagesWithReExecute会捕获状态码并跳转至/Error页面,但如果重定向的目标路由本身不存在,就会触发404,而非你预期的未授权状态码。
另外补充:用HttpStatusCode.MethodNotAllowed(405)表示权限问题不合适,405是指请求方法不被允许(比如用POST访问仅支持GET的接口),权限验证失败应使用HttpStatusCode.Unauthorized(401,未登录)或HttpStatusCode.Forbidden(403,无权限)。
修复步骤
修正过滤器的逻辑分支
给重定向代码添加else,确保Ajax请求返回状态码,非Ajax请求才执行重定向:protected void HandleUnauthorizedRequest(ActionExecutingContext context) { // 原有逻辑代码 if (context.HttpContext.Request.IsAjaxRequest()) { // 权限问题建议用401或403,而非405 context.Result = new StatusCodeResult((int)HttpStatusCode.Unauthorized); } else { context.Result = new RedirectToRouteResult(new RouteValueDictionary(new { action = "Index", controller = "Home" })); } }确保重定向目标路由存在
如果坚持重定向到Home/Index,需添加对应的HomeController并实现Index方法;或者将重定向目标改为已存在的路由(比如默认的Login/Index)。验证状态码中间件的行为
对于API请求,确保返回纯状态码而非重定向,避免触发不必要的页面跳转和404问题。
内容的提问来源于stack exchange,提问作者erikscandola

