我已在Angular 8和ASP.NET Web API,.NET Framework 4.7.2之间正常运行的SignalR通信。但是我已经几个月没有测试了,现在当我尝试在浏览器控制台中得到该结果时:
http://localhost:55454/signalr/negotiate? .... net :: ERR_ABORTED 404(未找到)
这几个月来唯一的主要变化是现在我的API使用Identity Server 3,但我不认为这是问题所在。
但是这里是我在Identity Server实施之前的启动代码:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true,
EnableDetailedErrors = true,
};
map.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions()
{
Provider = new QueryStringOAuthBearerProvider(),
AccessTokenProvider = new AuthenticationTokenProvider()
{
OnCreate = new Action<AuthenticationTokenCreateContext>(c =>
{
c.SetToken(c.SerializeTicket());
}),
OnReceive = new Action<AuthenticationTokenReceiveContext>(c =>
{
c.DeserializeTicket(c.Token);
c.OwinContext.Environment["Properties"] = c.Ticket.Properties;
})
},
});
map.RunSignalR(hubConfiguration);
});
和QueryStringOAuthBearerProvider(因为我在查询字符串中发送了令牌):
private class QueryStringOAuthBearerProvider : OAuthBearerAuthenticationProvider
{
public override Task RequestToken(OAuthRequestTokenContext context)
{
if (context != null)
{
var value = context.Request.Query.Get("token");
if (!string.IsNullOrEmpty(value))
{
context.Token = value;
}
}
return Task.FromResult<object>(null);
}
}
我尝试使用新代码,但结果仍然相同:
app.UseIdentityServerBearerTokenAuthentication(new
IdentityServerBearerTokenAuthenticationOptions
{
Authority = identityAuthority,
});
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration
{
EnableJSONP = true,
EnableDetailedErrors = true,
};
map.UseIdentityServerBearerTokenAuthentication(new IdentityServer3.AccessTokenValidation.IdentityServerBearerTokenAuthenticationOptions
{
Authority = identityAuthority,
TokenProvider = new QueryStringOAuthBearerProvider(),
});
map.RunSignalR(hubConfiguration);
});
}
我认为这不是主要问题,因为在Debug中,它永远不会达到QueryStringOAuthBearerProvider类中的断点。它必须是。
API中我的SignalR版本是2.4.1,所以它在Angular中(“ signalr”:“ ^ 2.4.1”,)我也使用“ ng2-signalr”:“ ^ 8.0.2” nuget保存一些手动编写的JS代码。
这里是打字稿中的一个例子(以前很奏效):
startConnection(hubConnection: SignalR): Promise<ISignalRConnection> {
console.log('Connecting...');
if (this.authService && this.authService.token) {
return hubConnection.connect({ jsonp: true, hubName: 'ChatHub', url: this.config.API_BASE_URL, qs: { token: this.authService.token } });
}
}
也许是启动配置,但可能不会导致看起来根本找不到这样的地址(localhost / signalr ...)已为该角度项目设置了CORS政策,所有其他常规API调用均正常运行。
我不知道为什么不久前我从某些功能上起了这个404错误的作用,而该功能只是一种魅力。
编辑:
在数据库中,我保留了Angular App的本地主机地址,并且给了他完整的CORS访问权限,但这对SignalR足够了吗?是的请求来自同一个本地主机,但不调用http://localhost:55454/api,而是调用http://localhost:55454/signalr,因此是否需要对CORS进行其他处理?我认为应该这样做,否则为什么要添加这行OLD代码:
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
有什么困难吗?
我已经解决了。最初的答复不是很详细。 404就是这样。但是当我深入时,我发现详细的响应是:
HTTP错误404.15-找不到请求过滤模块被配置为拒绝查询字符串太长的请求。
的确是。因此,现在我需要确定是否可以安全地增加URL和查询字符串的长度,如果没有,如何解决此问题。