Unable to implement SignalR Hub on IIS with windows authentification, works fine with IIS Express, negotiate fails 401 !
Is there an existing issue for this?
- [x] I have searched the existing issues
Describe the bug
Blazor Server application, SignalR hub fail in IIS environment. Works In development environment VS2022 with IIS Express !
Hubconnection.StartAsync() fail
Expected Behavior
Ability to establish connection to the hub from client connections with Windows authentication.
Hubconnection.StartAsync() should work.
Steps To Reproduce
https://github.com/akaioda/BlazorApp6
Exceptions (if any)
System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized). at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode() at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.GetNegotiationResponseAsync(Uri uri, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsyncCore(TransferFormat transferFormat, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken) at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken) at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken) at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncInner(CancellationToken cancellationToken) at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken) at BlazorApp6.Components.Pages.Home.<OnInitializedAsync>b__6_0() in C:\Users\USER123456\source\repos\akaioda\BlazorApp6\Components\Pages\Home.razor:line 126 at BlazorApp6.Components.Pages.Home.OnInitializedAsync() in C:\Users\USER123456\source\repos\akaioda\BlazorApp6\Components\Pages\Home.razor:line 78 at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync() at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
.NET Version
8.0.303
Anything else?
Notes : The network context is as follows. The Windows 2019 server is in a network zone that is accessed through a load balancer that provides SSL termination and carries the certificates. In my case, there is no load balancing per se, as there is only one target IIS 10 server, the environment is .net8, and it is a 100% intranet environment, including for clients. IIS is configured to use Windows authentication
Taken into account (see Home.razor) : SignalR negotiate fails from Blazor Server with windows authentication dotnet/aspnetcore#25000 [https://github.com/dotnet/aspnetcore/issues/25000#issuecomment-1877615925]
how to use impersonation when using Windows auth and SignalR from a Blazor Server app dotnet/aspnetcore#34618 [https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/blazor/fundamentals/signalr.md]
Wireshark trace on IIS server (anonymized) : DOM\USER null at 704.
No. Time Source Destination Protocol Length Info
393 10.359434 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 951 GET / HTTP/1.1
399 10.591392 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 195 HTTP/1.1 401 Unauthorized (text/html)
401 10.619752 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 1034 GET / HTTP/1.1 , NTLMSSP_NEGOTIATE
402 10.620323 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 890 HTTP/1.1 401 Unauthorized , NTLMSSP_CHALLENGE (text/html)
407 10.627486 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 230 GET / HTTP/1.1 , NTLMSSP_AUTH, User: MYDOM\USER123456
482 11.684344 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 59 HTTP/1.1 200 OK (text/html)
484 11.709732 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 1112 GET /app.css HTTP/1.1
488 11.712625 LB_BOX_IPA.131 IIS_SRV_IPA.168 HTTP 1126 GET /BlazorApp6.styles.css HTTP/1.1
490 11.712967 IIS_SRV_IPA.168 LB_BOX_IPA.131 HTTP 195 HTTP/1.1 401 Unauthorized (text/html)
493 11.722793 LB_BOX_IPA.131 IIS_SRV_IPA.168 HTTP 1209 GET /BlazorApp6.styles.css HTTP/1.1 , NTLMSSP_NEGOTIATE
494 11.723268 IIS_SRV_IPA.168 LB_BOX_IPA.131 HTTP 890 HTTP/1.1 401 Unauthorized , NTLMSSP_CHALLENGE (text/html)
499 11.724754 LB_BOX_IPA.132 IIS_SRV_IPA.168 HTTP 1115 GET /_framework/blazor.web.js HTTP/1.1
501 11.725033 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 1017 HTTP/1.1 200 OK (text/css)
503 11.725274 IIS_SRV_IPA.168 LB_BOX_IPA.132 HTTP 195 HTTP/1.1 401 Unauthorized (text/html)
507 11.725984 LB_BOX_IPA.131 IIS_SRV_IPA.168 HTTP 405 GET /BlazorApp6.styles.css HTTP/1.1 , NTLMSSP_AUTH, User: MYDOM\USER123456
513 11.735904 IIS_SRV_IPA.168 LB_BOX_IPA.131 HTTP 311 HTTP/1.1 304 Not Modified
517 11.740033 LB_BOX_IPA.132 IIS_SRV_IPA.168 HTTP 1198 GET /_framework/blazor.web.js HTTP/1.1 , NTLMSSP_NEGOTIATE
518 11.740419 IIS_SRV_IPA.168 LB_BOX_IPA.132 HTTP 890 HTTP/1.1 401 Unauthorized , NTLMSSP_CHALLENGE (text/html)
522 11.744921 LB_BOX_IPA.132 IIS_SRV_IPA.168 HTTP 394 GET /_framework/blazor.web.js HTTP/1.1 , NTLMSSP_AUTH, User: MYDOM\USER123456
530 11.753710 IIS_SRV_IPA.168 LB_BOX_IPA.132 HTTP 343 HTTP/1.1 304 Not Modified
534 11.808395 LB_BOX_IPA.132 IIS_SRV_IPA.168 HTTP 1049 GET /_blazor/initializers HTTP/1.1
537 11.816988 IIS_SRV_IPA.168 LB_BOX_IPA.132 HTTP/JSON 59 HTTP/1.1 200 OK , JSON (application/json)
539 11.818836 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 1078 GET /favicon.ico HTTP/1.1
541 11.820223 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 59 HTTP/1.1 404 Not Found
544 11.834705 LB_BOX_IPA.132 IIS_SRV_IPA.168 HTTP 1267 POST /_blazor/negotiate?negotiateVersion=1 HTTP/1.1
545 11.846097 IIS_SRV_IPA.168 LB_BOX_IPA.132 HTTP/JSON 553 HTTP/1.1 200 OK , JSON (application/json)
550 11.858801 LB_BOX_IPA.130 IIS_SRV_IPA.168 HTTP 1018 GET /_blazor?id=Zcwgu6iTkFOBbFhjzBnlBg HTTP/1.1
552 11.859234 IIS_SRV_IPA.168 LB_BOX_IPA.130 HTTP 195 HTTP/1.1 401 Unauthorized (text/html)
554 11.870701 LB_BOX_IPA.130 IIS_SRV_IPA.168 HTTP 1101 GET /_blazor?id=Zcwgu6iTkFOBbFhjzBnlBg HTTP/1.1 , NTLMSSP_NEGOTIATE
555 11.871118 IIS_SRV_IPA.168 LB_BOX_IPA.130 HTTP 890 HTTP/1.1 401 Unauthorized , NTLMSSP_CHALLENGE (text/html)
558 11.874242 LB_BOX_IPA.130 IIS_SRV_IPA.168 HTTP 297 GET /_blazor?id=Zcwgu6iTkFOBbFhjzBnlBg HTTP/1.1 , NTLMSSP_AUTH, User: MYDOM\USER123456
564 11.888102 IIS_SRV_IPA.168 LB_BOX_IPA.130 HTTP 294 HTTP/1.1 101 Switching Protocols
645 12.166339 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 409 POST /chathub/negotiate?negotiateVersion=1 HTTP/1.1
647 12.166789 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 195 HTTP/1.1 401 Unauthorized (text/html)
698 12.204528 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 492 POST /chathub/negotiate?negotiateVersion=1 HTTP/1.1 , NTLMSSP_NEGOTIATE
699 12.204986 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 890 HTTP/1.1 401 Unauthorized , NTLMSSP_CHALLENGE (text/html)
704 12.207610 LB_BOX_IPA.129 IIS_SRV_IPA.168 HTTP 600 POST /chathub/negotiate?negotiateVersion=1 HTTP/1.1 , NTLMSSP_AUTH, User: \
706 12.208425 IIS_SRV_IPA.168 LB_BOX_IPA.129 HTTP 195 HTTP/1.1 401 Unauthorized (text/html)
1138 23.438988 LB_BOX_IPA.132 IIS_SRV_IPA.168 HTTP 413 POST /_blazor/disconnect HTTP/1.1
1142 23.448608 IIS_SRV_IPA.168 LB_BOX_IPA.132 HTTP 59 HTTP/1.1 200 OK
APP Log on IIS server :
2025-08-25 10:48:00.591 +02:00 [DBG] Registered SignalR Protocol: json, implemented by Microsoft.AspNetCore.SignalR.Protocol.JsonHubProtocol.
2025-08-25 10:48:00.592 +02:00 [DBG] Registered SignalR Protocol: blazorpack, implemented by Microsoft.AspNetCore.Components.Server.BlazorPack.BlazorPackHubProtocol.
2025-08-25 10:48:00.672 +02:00 [INF] Deferring to the server's implementation of Windows Authentication.
2025-08-25 10:48:00.723 +02:00 [INF] Application started. Press Ctrl+C to shut down.
2025-08-25 10:48:00.723 +02:00 [INF] Hosting environment: Production
2025-08-25 10:48:00.723 +02:00 [INF] Content root path: C:\inetpub\wwwroot\BlazorApp6
2025-08-25 10:48:00.747 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/ - null null
2025-08-25 10:48:00.763 +02:00 [WRN] Failed to determine the https port for redirect.
2025-08-25 10:48:00.776 +02:00 [INF] Executing endpoint '/ (/)'
2025-08-25 10:48:00.926 +02:00 [INF] Executed endpoint '/ (/)'
2025-08-25 10:48:00.931 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/ - 200 null text/html; charset=utf-8 184.8248ms
2025-08-25 10:48:00.953 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/app.css - null null
2025-08-25 10:48:00.969 +02:00 [INF] Sending file. Request path: '/app.css'. Physical path: 'C:\inetpub\wwwroot\BlazorApp6\wwwroot\app.css'
2025-08-25 10:48:00.969 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/app.css - 200 2154 text/css 15.6624ms
2025-08-25 10:48:00.975 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/BlazorApp6.styles.css - null null
2025-08-25 10:48:00.978 +02:00 [INF] The file /BlazorApp6.styles.css was not modified
2025-08-25 10:48:00.978 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/BlazorApp6.styles.css - 304 null text/css 3.1244ms
2025-08-25 10:48:00.994 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/_framework/blazor.web.js - null null
2025-08-25 10:48:00.995 +02:00 [INF] Executing endpoint 'Blazor web static files'
2025-08-25 10:48:00.996 +02:00 [INF] The file /_framework/blazor.web.js was not modified
2025-08-25 10:48:00.996 +02:00 [INF] Executed endpoint 'Blazor web static files'
2025-08-25 10:48:00.996 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/_framework/blazor.web.js - 304 null text/javascript 1.8019ms
2025-08-25 10:48:01.052 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/_blazor/initializers - null null
2025-08-25 10:48:01.052 +02:00 [INF] Executing endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:01.059 +02:00 [INF] Executed endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:01.059 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/_blazor/initializers - 200 null application/json; charset=utf-8 7.793ms
2025-08-25 10:48:01.062 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/favicon.ico - null null
2025-08-25 10:48:01.063 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/favicon.ico - 404 null null 0.7971ms
2025-08-25 10:48:01.063 +02:00 [INF] Request reached the end of the middleware pipeline without being handled by application code. Request path: GET http://myhost.mydomain.com/favicon.ico, Response status code: 404
2025-08-25 10:48:01.078 +02:00 [INF] Request starting HTTP/1.1 POST http://myhost.mydomain.com/_blazor/negotiate?negotiateVersion=1 - null 0
2025-08-25 10:48:01.080 +02:00 [INF] Executing endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:01.084 +02:00 [DBG] New connection WDu9xVlBlaieev0XJetpaA created.
2025-08-25 10:48:01.088 +02:00 [DBG] Sending negotiation response.
2025-08-25 10:48:01.089 +02:00 [INF] Executed endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:01.089 +02:00 [INF] Request finished HTTP/1.1 POST http://myhost.mydomain.com/_blazor/negotiate?negotiateVersion=1 - 200 316 application/json 10.3456ms
2025-08-25 10:48:01.124 +02:00 [INF] Request starting HTTP/1.1 GET http://myhost.mydomain.com/_blazor?id=Zcwgu6iTkFOBbFhjzBnlBg - null null
2025-08-25 10:48:01.124 +02:00 [INF] Executing endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:01.127 +02:00 [DBG] Establishing new connection.
2025-08-25 10:48:01.130 +02:00 [DBG] OnConnectedAsync started.
2025-08-25 10:48:01.132 +02:00 [DBG] Socket opened using Sub-Protocol: 'null'.
2025-08-25 10:48:01.144 +02:00 [DBG] Found protocol implementation for requested protocol: blazorpack.
2025-08-25 10:48:01.147 +02:00 [DBG] Completed connection handshake. Using HubProtocol 'blazorpack'.
2025-08-25 10:48:01.172 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "0", Target: "StartCircuit", Arguments: [ https://pecodsi.urssaf.recouv/, https://pecodsi.urssaf.recouv/, [], CfDJ8AZe+klKAG9FitXUnFgRJ3vRx6CLYzNV9Mpxn+sV5Pk4nwkrwSyrNwxHdjchdfUqdFl2gi7nO6q9cwwOXTrVQOew2XC4s6tY8aQY4es/enhFDv4e9xFmvoFzaWsUCcikqZp4VuXFRa4p2rofjUq+2ehumxMWwsCeKza4ssNDmUtj2nKCu8l5I25QsoMtVtg4Zmuus9yZqPKhLDvcbvv2+0K4nmVFqx+Ueo6c9rLaurJcmUYHW31rWHLnwQV9jMD9eTLbTRph1sKxm7UJqYF3ZUsH6qFaaJ6xvSCO32OWabZ7RiN1Yr3kk+D6jPrLI+LkO+dK3eLYvRQO8Sfw8Rnq8vuEMUai09D1snnA+dBVeF8w6iAda6pQ4osiSfBCGP1QAOiGgieeHMuE2VPVgqwvXJn17pq7o4MrBqts6vZ835vMkfRqMpQS9LvQfDkmKObu0kIV5IOrWMsP+gUp4iTpLToEYwNS6PGzI86tvjUdl2Oy1hre0jmisACZATrCTVirdpzPdI//JWukmxnGiM8Qc/4PwfkIRhwRes60fhFpgftlSmGVl4acJZuDAvqaDQl/vZdT7uXaCfm6NIp3qT9+oBbjv31Fb4xdANwxCwSyiTvU ], StreamIds: [ ] }.
2025-08-25 10:48:01.220 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 2, True, [2,true,null] ], StreamIds: [ ] }.
2025-08-25 10:48:01.224 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "UpdateRootComponents", Arguments: [ {"batchId":1,"operations":[{"type":"add","ssrComponentId":1,"marker":{"type":"server","prerenderId":"22b64ae9dd414761871d614871e49c61","key":{"locationHash":"77D12F14A8105320B1AAED6AE7E689DA0EC4483270A645E84079EAA0FFDF550D:5","formattedComponentKey":""},"sequence":0,"descriptor":"CfDJ8AZe+klKAG9FitXUnFgRJ3vgFTb/BYgs+LbWgIqrgZ3r7X926o0YaU5XaoJqiWi1MTYVBV2RCXrOL0NM8fnADuQleSzSSV5e5JowBUSYF3oudAj/9LRzgaikJU6n9akUpkOSfD7lXXT3gGo58+TeXIrcdOkXkon/gmhT9PKISPgojY7cQkoDWYMGiU3nOTGdLYVhJ02BegK4UrG7lXViuTeBbbl5gh4EwmHlg8NWXVu24QTtcAA89kfRJD9anZ+nFE3DEJ08E7s+N5PQFK4g7MQkU98ZIhgv/YaCHF3emSZqAqFJn6FnfUsbvp12IYX1R7Tu5zfN/XxkZvk5XLoLqmerFYQlTVeV57qdEWN5EyZxj3gUTuYHkznJHAuLBh+Bf7nJL3bN5nbq+kMEYkVj9dqKVvyUmdfMIgO1Gkf3TTbqNa2GnSIys8cBbtQ5e0QtU2Zm6CmYPT31ab0JTbxULvYO+8o0+cR9evq1Uy1WrOlpoJpVS5a0YQCZJXYi0qbkOgiRt/+rB3/S10rPC88I9zOUn3YKaqJKYJOwL0Ql/m4hbXlkswrFobA+ITBXel5BILbsIFDIVA/iHdWE2T5Fh/E=","uniqueId":0}},{"type":"add","ssrComponentId":2,"marker":{"type":"server","key":{"locationHash":"302210BE96CD5C1828A8E2C33F34201FFDD2C760924B9C42E344BA402475A0DD:8","formattedComponentKey":""},"sequence":1,"descriptor":"CfDJ8AZe+klKAG9FitXUnFgRJ3sUMe79USccbhSVui0iOhNr2xGHHpJZXYxbh2z2/j3YhSbec+MiNbAOXM45AIP+4a1oppY0j2+w8R4OJt1g7OBo+owIgP3xzwGYN1pTY0brbbjDeoejLh1p0fsKCapbtQldtocxceXTMVzBNDXYG1guHFBx7qUP00NPuIwNVhpyPEttPmOxuprBAoCwPw7XMgepiNMJG56Wx1YvBUPohuJ+L8YZQxioRJUpzVKz1IG3WbdPIEBH19jXIahirfg+pZWTRC4RZlQYLQgMyarAIGpAXzyu4mSv7L0zzrbShVV3ofUOC9TUS7j8TCV8E16stQNorqT28d8Z8MjF/sxuu4i3zLZpb9NoSEHDqR+oltdLQN5cgC92hElwOWtK24AUu+cwwY9zTdf/O/iAf3c+/fVvAP0Re2O1YF4WLCKd57XpQYfFldc4lF1P2y9mwDt7ngxBnkTCivKCy9efWuHZ0ub5mWrebst9ZZBFS3B1kMZQH6cxplK4IwQBUhl2gp7yz4k=","uniqueId":1}}]}, CfDJ8AZe+klKAG9FitXUnFgRJ3vRx6CLYzNV9Mpxn+sV5Pk4nwkrwSyrNwxHdjchdfUqdFl2gi7nO6q9cwwOXTrVQOew2XC4s6tY8aQY4es/enhFDv4e9xFmvoFzaWsUCcikqZp4VuXFRa4p2rofjUq+2ehumxMWwsCeKza4ssNDmUtj2nKCu8l5I25QsoMtVtg4Zmuus9yZqPKhLDvcbvv2+0K4nmVFqx+Ueo6c9rLaurJcmUYHW31rWHLnwQV9jMD9eTLbTRph1sKxm7UJqYF3ZUsH6qFaaJ6xvSCO32OWabZ7RiN1Yr3kk+D6jPrLI+LkO+dK3eLYvRQO8Sfw8Rnq8vuEMUai09D1snnA+dBVeF8w6iAda6pQ4osiSfBCGP1QAOiGgieeHMuE2VPVgqwvXJn17pq7o4MrBqts6vZ835vMkfRqMpQS9LvQfDkmKObu0kIV5IOrWMsP+gUp4iTpLToEYwNS6PGzI86tvjUdl2Oy1hre0jmisACZATrCTVirdpzPdI//JWukmxnGiM8Qc/4PwfkIRhwRes60fhFpgftlSmGVl4acJZuDAvqaDQl/vZdT7uXaCfm6NIp3qT9+oBbjv31Fb4xdANwxCwSyiTvU ], StreamIds: [ ] }.
2025-08-25 10:48:01.373 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "OnRenderCompleted", Arguments: [ 2, ], StreamIds: [ ] }.
2025-08-25 10:48:01.376 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "OnRenderCompleted", Arguments: [ 3, ], StreamIds: [ ] }.
2025-08-25 10:48:01.378 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 3, True, [3,true,null] ], StreamIds: [ ] }.
2025-08-25 10:48:01.383 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 4, True, [4,true,null] ], StreamIds: [ ] }.
2025-08-25 10:48:01.401 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "EndInvokeJSFromDotNet", Arguments: [ 5, True, [5,true,null] ], StreamIds: [ ] }.
2025-08-25 10:48:01.425 +02:00 [DBG] Received hub invocation: InvocationMessage { InvocationId: "", Target: "OnRenderCompleted", Arguments: [ 4, ], StreamIds: [ ] }.
2025-08-25 10:48:01.463 +02:00 [WRN] Unhandled exception rendering component: Response status code does not indicate success: 401 (Unauthorized).
System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.GetNegotiationResponseAsync(Uri uri, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsyncCore(TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncInner(CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
at BlazorApp6.Components.Pages.Home.<OnInitializedAsync>b__6_0() in C:\Users\USER123456\source\repos\akaioda\BlazorApp6\Components\Pages\Home.razor:line 126
at BlazorApp6.Components.Pages.Home.OnInitializedAsync() in C:\Users\USER123456\source\repos\akaioda\BlazorApp6\Components\Pages\Home.razor:line 78
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
2025-08-25 10:48:01.504 +02:00 [ERR] Unhandled exception in circuit 'bmXnhrXXSwBWyPMAKAx-abGGh9oduSMiq-uD5Vf634I'.
System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.NegotiateAsync(Uri url, HttpClient httpClient, ILogger logger, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.GetNegotiationResponseAsync(Uri uri, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.SelectAndStartTransport(TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsyncCore(TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnection.StartAsync(TransferFormat transferFormat, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.Connections.Client.HttpConnectionFactory.ConnectAsync(EndPoint endPoint, CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncCore(CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsyncInner(CancellationToken cancellationToken)
at Microsoft.AspNetCore.SignalR.Client.HubConnection.StartAsync(CancellationToken cancellationToken)
at BlazorApp6.Components.Pages.Home.<OnInitializedAsync>b__6_0() in C:\Users\USER123456\source\repos\akaioda\BlazorApp6\Components\Pages\Home.razor:line 126
at BlazorApp6.Components.Pages.Home.OnInitializedAsync() in C:\Users\USER123456\source\repos\akaioda\BlazorApp6\Components\Pages\Home.razor:line 78
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)
2025-08-25 10:48:01.511 +02:00 [DBG] OnConnectedAsync ending.
2025-08-25 10:48:01.512 +02:00 [DBG] Waiting for the application to finish sending data.
2025-08-25 10:48:01.512 +02:00 [DBG] Socket closed.
2025-08-25 10:48:01.513 +02:00 [DBG] Removing connection Zcwgu6iTkFOBbFhjzBnlBg from the list of connections.
2025-08-25 10:48:01.514 +02:00 [INF] Executed endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:01.515 +02:00 [INF] Request finished HTTP/1.1 GET http://myhost.mydomain.com/_blazor?id=Zcwgu6iTkFOBbFhjzBnlBg - 101 null null 390.959ms
2025-08-25 10:48:12.683 +02:00 [INF] Request starting HTTP/1.1 POST http://myhost.mydomain.com/_blazor/disconnect - multipart/form-data; boundary=----WebKitFormBoundaryxRVRIRPt4GJerZI1 359
2025-08-25 10:48:12.683 +02:00 [INF] Executing endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:12.691 +02:00 [INF] Executed endpoint 'Microsoft.AspNetCore.Routing.RouteEndpoint'
2025-08-25 10:48:12.691 +02:00 [INF] Request finished HTTP/1.1 POST http://myhost.mydomain.com/_blazor/disconnect - 200 null null 8.6101ms
2025-08-25 10:51:04.023 +02:00 [INF] Application is shutting down...
@akaioda thanks for contacting us.
Does your code work on an app with SignalR app that doesn't involve Blazor?
That is, a signalr app with a SignalR Hub where you are using the HubClient in the same way you are right now.
Hi @javiercn, thnaks for your attention !
I haven't tested this case because the core of the actual application (not the minimal example attached to report the issue) is built with Blazor...
Hi @javiercn, thnaks for your attention !
I haven't tested this case because the core of the actual application (not the minimal example attached to report the issue) is built with Blazor...
The reason that I ask is because there shouldn't be anything Blazor specific to this, AFAIK.
Blazor runs inside a SignalR hub and as long as that work, we should be no different, if it doesn't work I'm not sure if this requires additional signalr config.
The other question/thing to account for is making sure that what you are trying to do makes sense. Hubconnection.StartAsync() runs as part of the server, not in the browser. If you are trying to do a loopback connection, that might be problematic and might not be what you are looking for.
The ultimate goal is to be able to notify all open views of a change and respond to it or not ;-). To do this, the idea was to integrate a connection to the hub into MainLayout.razor and be able to receive hidden notifications, typically changes in rights, with immediate consideration. For example, the visibility of a control in the UI. To do this, we customize the claims, and the message received forces clients to reread them. So far, this works without any problems with IIS Express in VS 2022.
@akaioda thanks for the additional details.
All the open views for a given browser/customer?
If this is for a single user/browser that has multiple opened windows/tabs, you could consider using https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel for communicating across tabs
@javiercn , no, communication must be possible with any client (user) using the Blazor application. The hub is designed to be configured to listen in the MainLayout.razor file, so that any tab opened to the application, regardless of the browser, will receive the notification and the user interface can respond accordingly. These are the basics, which have been implemented.
@BrennanConroy are there docs on how to make this work with SignalR?
I don't think there's anything Blazor specific here.
I don't think there's anything Blazor specific here.
@javiercn That is also my opinion, thank you for pointing that out. π
Your app works for me in IIS Express and IIS. That implies an environment specific issue.
The Windows 2019 server is in a network zone that is accessed through a load balancer that provides SSL termination and carries the certificates.
Does that mean when the HubConnection code in the Blazor Component runs it's hitting the load balancer? If it doesn't hit the load balancer with SSL does that cause problems? If you remove the load balancer for testing does the scenario work?
Hi, @BrennanConroy We are in this configuration!
Your app works for me in IIS Express and IIS. That implies an environment specific issue.
πI agree
Does that mean when the HubConnection code in the Blazor Component runs it's hitting the load balancer?
yes
If you remove the load balancer for testing does the scenario work?
I can't in my context π
If I'm not mistaken, in this connection phase, the server initiates a request to itself, and name resolution involves going through the LB. I tried to keep it internal by defining an entry in the server's Hosts file to keep it within the server's security domain. That also failed, but not in the same way, which gave me a clue about the target URL.
System.Net.Http.HttpRequestException: No connection could be established because the target machine actively refused it. (myhost.mydomain.com:443)
---> System.Net.Sockets.SocketException (10061): No connection could be established because the target machine actively refused it.
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken)
at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)...
Is it possible to configure the request, host name, and port/protocol differently? Would that be a possible solution? Is there any chance of finding a workable solution with this network architecture?
regards
Is it possible to configure the request, host name, and port/protocol differently?
Sure, you can build the URI yourself using UriBuilder. e.g. new UriBuilder(Navigation.ToAbsoluteUri("/chathub")) { Scheme = "http", Port = 80 }.ToString()
Is there any chance of finding a workable solution with this network architecture?
Probably, but since it's likely some configuration in your load balancer that needs updating, we can't really help much.
Hey, finally a result!
@BrennanConroy The test application related to this issue now works for me too in both environments with two modifications.
I configured the URI customization this way to address the case in development with IIS Express, and the case in βproductionβ on the target IIS server:
#if DEBUG
// using IIS express here
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri("/chathub"),
config =>
{
config.UseDefaultCredentials = true;
})
.WithAutomaticReconnect()
.Build();
#else
// using IIS in a production environment release build
var hostName = Environment.MachineName;
var addresses = Dns.GetHostAddresses(hostName);
var ipv4 = addresses.FirstOrDefault(addresses => addresses.AddressFamily == AddressFamily.InterNetwork)?.ToString();
var uriBuilded = new UriBuilder(Navigation.ToAbsoluteUri("/chathub")) { Scheme = "http", Port = 80, Host=ipv4}.ToString();
Log.LogInformation("chathub URI builded [{uriBuilded}]", uriBuilded);
hubConnection = new HubConnectionBuilder()
.WithUrl(Navigation.ToAbsoluteUri(uriBuilded),
config =>
{
config.UseDefaultCredentials = true;
})
.WithAutomaticReconnect()
.Build();
#endif
And I had to modify the bindings in the IIS configuration as follows by adding the line circled in green:
However, no URI configuration for the host name, other than using the actual IP address of the server, seems to work. I haven't figured out why yet, so if anyone has an explanation, I'm all ears π
In the meantime, I also explored a solution based on JavaScript functions with JS Interop, which allowed me to work around the problem using a different approach.
Ultimately, I'm not going to use this method, which involves integrating the SignalR javascript package on the client side, and requires partial exposure of javascript methods with message processing logic, necessary for interoperability with the underlying code of razor components. IMHO, in my context, from the point of view of improving security, this method seems less appropriate!
regards
Hello,
I think this thread can now be closed, but @BrennanConroy, perhaps it would be a good idea for the aspnetcore/SignalR team to add some official implementation guidelines to the documentation for those who have a similar network configuration, which I believe must be quite common!
Best regards
Moving to the docs repo, as it looks like a docs update is the action to consider here.
ποΈπ Summertime!! Woot!! πβ΅
Stand-by! ... A green dinosaur π¦ will be along shortly to assist.
We have an article for various proxy/load balancer scenarios at ...
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer
We have a SignalR hosting and scaling article at ...
https://learn.microsoft.com/en-us/aspnet/core/signalr/scale
There's the SignalR configuration article ...
https://learn.microsoft.com/en-us/aspnet/core/signalr/configuration
@danroth27 ... Do you want this covered at all? If so, where would you like the guidance placed?
@mikekistler @BrennanConroy What are your thoughts on where this documentation should go?