.NET Core 2.0启用Windows Auth后自定义403错误页失效问题
我帮你梳理下可能遗漏的配置环节,结合ASP.NET Core 2.0的特性,这几个点是最容易出问题的:
1. 中间件顺序搞错了!
ASP.NET Core的中间件是按注册顺序执行的,UseStatusCodePagesWithReExecute这类状态码处理中间件必须放在认证、授权和MVC中间件之前,否则请求已经被后续中间件处理并返回403了,状态码中间根本没机会捕获。
正确的Configure方法顺序应该是这样的:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); // 开发环境也可以加上状态码中间件测试 app.UseStatusCodePagesWithReExecute("/Home/Error/{0}"); } else { // 生产环境先注册状态码处理 app.UseStatusCodePagesWithReExecute("/Home/Error/{0}"); } // 然后是认证、授权中间件 app.UseAuthentication(); app.UseAuthorization(); // 最后是MVC路由 app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
2. Error方法的路由匹配有问题
你需要确保HomeController里的Error方法能正确接收状态码参数,并且路由能匹配上。比如用/Home/Error/{0}的配置,对应的Controller方法应该是:
// 加上Route特性确保路由匹配 [Route("Home/Error/{statusCode}")] public IActionResult Error(int statusCode) { ViewData["StatusCode"] = statusCode; // 返回对应状态码的视图,比如403.cshtml return View(statusCode.ToString()); }
如果用的是带查询参数的app.UseStatusCodePagesWithReExecute("/Home/Error", "?statusCode={0}"),方法要改成支持可选参数:
public IActionResult Error(int? statusCode) { var code = statusCode ?? 500; ViewData["StatusCode"] = code; return View(code.ToString()); }
另外要确认/Views/Error/403.cshtml的路径正确,并且视图的Build Action设置为Content。
3. IIS环境下需要额外配置
如果你的应用部署在IIS上,默认IIS会自己处理403错误,不会转发给ASP.NET Core应用。这时候需要在web.config里添加httpErrors配置,让IIS把403请求交给应用处理:
<configuration> <system.webServer> <httpErrors errorMode="Custom" existingResponse="Replace"> <remove statusCode="403" subStatusCode="-1" /> <error statusCode="403" path="/Home/Error/403" responseMode="ExecuteURL" /> </httpErrors> </system.webServer> </configuration>
如果是用IIS Express调试,也可以检查下项目的web.config是否有这个配置。
4. 确认授权策略确实返回403
先验证你的AD组授权配置是否正确,确保未授权用户访问时确实返回的是403,而不是其他状态码。比如在ConfigureServices里的授权策略:
services.AddAuthorization(options => { options.AddPolicy("ADGroupAccess", policy => policy.RequireRole("YOUR_DOMAIN\\YourADSecurityGroup")); });
然后在Controller或Action上加上[Authorize(Policy = "ADGroupAccess")],测试时用不在AD组的账号访问,确认返回的是403状态码(可以用浏览器开发者工具查看网络请求的状态码)。
按照这几个步骤排查,应该就能让自定义403错误页生效了。
内容的提问来源于stack exchange,提问作者Xiao Han

