基于ASP.NET Core的IdentityServer4应用浏览后堆栈溢出崩溃求助
解决IdentityServer4 + ASP.NET Core的Stack Overflow错误
从你贴的命令行日志和Startup代码来看,这个栈溢出十有八九是无限递归调用搞出来的,我给你梳理几个排查方向:
1. 先排查自定义扩展方法的问题
你用了好几个自定义的扩展方法,这些是最容易出递归bug的地方:
services.AddIdentityServer(Configuration):默认IdentityServer的注册是AddIdentityServer()不带参数的,你这个带Configuration的重载应该是自己写的扩展吧?如果这个方法内部不小心循环调用了服务注册逻辑,或者错误地重复配置了某些会触发递归的组件,直接就会把栈撑爆。app.UseMongoDbForIdentityServer():这个中间件的实现如果有问题,比如处理请求时不小心触发了重复的管道调用,或者内部有递归逻辑,也会引发栈溢出。
建议先把这些自定义扩展注释掉,换成IdentityServer的默认注册方式试试:
// 替换你的自定义AddIdentityServer services.AddIdentityServer() .AddInMemoryClients(/* 这里填你的客户端配置 */) .AddInMemoryApiScopes(/* 你的API范围配置 */) .AddInMemoryIdentityResources(/* 你的身份资源配置 */) .AddDeveloperSigningCredential(); // 开发环境临时用,生产记得换正式证书
同时把app.UseMongoDbForIdentityServer();也注释掉,然后重新跑应用,如果栈溢出消失了,那问题肯定就出在这些自定义方法里,回去找递归逻辑就行。
2. 调整中间件顺序
ASP.NET Core的中间件顺序绝对不能乱,你现在的Configure方法里顺序有问题:
app.UseIdentityServer()应该放在app.UseRouting()之后、app.UseAuthorization()之前才对。你之前把它放在了UseRouting()前面,虽然不一定直接导致栈溢出,但可能引发请求处理的异常,间接触发递归。
正确的顺序应该是这样的:
app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseSpaStaticFiles(); app.UseRouting(); // 先路由匹配 app.UseIdentityServer(); // IdentityServer要在授权前 app.UseAuthorization(); // 然后是Swagger相关 app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"); }); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller}/{action=Index}/{id?}"); }); app.UseSpa(spa => { spa.Options.SourcePath = "ClientApp"; if (env.IsDevelopment()) { spa.UseReactDevelopmentServer(npmScript: "start"); } });
3. 修复重复的服务注册
你在ConfigureServices里两次调用了services.AddControllersWithViews():
services.AddControllersWithViews(); // ... 中间一堆代码 ... services.AddControllersWithViews().AddRazorRuntimeCompilation();
虽然重复注册不一定直接导致栈溢出,但可能会引发服务容器的冲突,建议合并成一次:
services.AddControllersWithViews().AddRazorRuntimeCompilation();
4. 排查SPA中间件的循环重定向
如果你的React开发服务器和ASP.NET Core应用之间的请求转发有问题,可能会触发循环重定向,最终导致栈溢出。你可以先注释掉spa.UseReactDevelopmentServer(npmScript: "start");,直接跑ASP.NET Core应用,访问https://localhost:5001看看还会不会报错。
最后一招:抓详细栈跟踪
如果上面的步骤都没解决,建议用.NET的跟踪工具抓一下详细的调用栈:
- 启动应用,找到进程ID(可以用
dotnet ps命令查看) - 运行
dotnet trace collect -p <你的进程ID> - 触发报错后停止跟踪,打开生成的trace文件分析,就能看到到底是哪个方法在无限递归了。
内容的提问来源于stack exchange,提问作者San Jaisy
相关产品推荐
相关产品推荐

