部署带Identity的ASP.NET Core托管Blazor WASM到IIS功能异常求助
问题原因
你遇到的问题核心是默认ASP.NET Core Hosted模式的Blazor WASM模板默认设计为Server项目托管Client静态资源,二者运行在同一个域名端口下,你将两者拆分部署到不同端口,违背了默认配置逻辑,具体对应报错的根因如下:
- 你看到的
JSON.parse报错:Client默认配置的身份服务请求地址是自身域名端口,请求_configuration/oidc这类身份配置接口时,返回的是Client站点的404 HTML页面,非预期的JSON格式,解析直接失败,导致身份校验卡住停在「Authorizing」状态 - Server单独访问空白:Server默认配置了根路径 fallback到Client的
index.html,单独部署Server时站点内没有对应静态资源,所以返回空白页面 - 跨域限制:即便你改了请求地址,不同端口属于跨域场景,默认没有配置CORS策略,IdentityServer会直接拦截Client的跨域请求
解决方案
方案一:合并部署(推荐,符合模板设计,改造成本最低)
不需要拆分两个站点部署,直接发布Server项目即可,模板构建时会自动将Client的编译产物打包到Server的wwwroot目录下,你只需要在IIS新建一个站点指向Server的发布目录,二者就会运行在同一个端口,和本地开发的运行逻辑完全一致,不需要修改任何代码即可恢复所有功能。
方案二:必须拆分部署到不同端口的修改步骤
如果你确实需要分开部署两个站点,按如下步骤修改代码:
修改Client的
Program.cs配置- 将HttpClient的BaseAddress替换为你的Server站点实际访问地址
- 给ApiAuthorization指定IdentityServer的服务端地址
public class Program { public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); // 替换为你的Server站点实际地址 var serverBaseAddress = "https://你的Server域名:端口/"; builder.Services.AddHttpClient("Clients.Admin.ServerAPI", client => client.BaseAddress = new Uri(serverBaseAddress)) .AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>(); builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>().CreateClient("Clients.Admin.ServerAPI")); // 新增配置指定IdentityServer服务端地址 builder.Services.AddApiAuthorization(options => { options.ProviderOptions.Authority = serverBaseAddress; }); await builder.Build().RunAsync(); } }修改Server的
Startup.cs,新增CORS配置
在ConfigureServices方法中添加CORS策略:public void ConfigureServices(IServiceCollection services) { // 新增CORS配置,放在其他服务配置前面即可 services.AddCors(options => { options.AddPolicy("AllowBlazorClient", policy => { // 替换为你的Client站点实际访问地址 policy.WithOrigins("https://你的Client域名:端口") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); // 原有其他配置保留不变 services.AddDatabaseDeveloperPageExceptionFilter(); // ... 其余原有代码不用改 }在
Configure方法中启用CORS,注意要放在UseRouting之后、UseIdentityServer之前:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // 原有配置保留不变 if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseMigrationsEndPoint(); app.UseWebAssemblyDebugging(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseBlazorFrameworkFiles(); app.UseStaticFiles(); app.UseRouting(); // 新增启用CORS app.UseCors("AllowBlazorClient"); app.UseIdentityServer(); app.UseAuthentication(); app.UseAuthorization(); // 原有端点配置保留不变 app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); endpoints.MapControllers(); endpoints.MapFallbackToFile("index.html"); }); }修改Server的
appsettings.json,配置IdentityServer客户端白名单
新增IdentityServer的客户端配置,允许你的Client站点回调:"IdentityServer": { "Clients": { "Clients.Admin.Client": { "Profile": "IdentityServerSPA", "RedirectUris": ["https://你的Client域名:端口/authentication/login-callback"], "PostLogoutRedirectUris": ["https://你的Client域名:端口/authentication/logout-callback"] } } }
额外校验点
- 确认IIS已经安装了和你开发版本一致的ASP.NET Core托管捆绑包
- 两个站点都必须配置HTTPS,IdentityServer默认要求HTTPS访问,否则会触发安全策略拦截
- 生产环境请替换
builder.AddDeveloperSigningCredential()为正式的签名证书,不要用开发者临时证书
内容的提问来源于stack exchange,提问作者yithril
相关产品推荐
相关产品推荐

