我正在尝试从blazor Webassembly客户端连接到SignalR服务,但是我认为这在CORS上失败。这是我的剃须刀文件中的代码。
m_connection = new HubConnectionBuilder()
.WithUrl(myMircoServiceUrl, options =>
{
options.AccessTokenProvider = () => Task.FromResult(userService.Token);
})
.WithAutomaticReconnect()
.Build();
await m_connection.StartAsync();
然后在webassembly日志中,我看到以下错误:
对从原点'http://localhost:5010'处'xxxx / negotiate?negotiateVersion = 1'处提取的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:否'Access-Control-Allow -Origin'标头出现在请求的资源上。如果不透明的响应满足您的需求,请将请求的模式设置为“ no-cors”以在禁用CORS的情况下获取资源。
我在Blazor服务器配置中添加了以下CORS策略,在微服务配置中添加了类似的内容:
app.UseResponseCompression();
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBlazorDebugging();
}
else
{
app.UseExceptionHandler(@"/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseAuthorization();
app.UseCors(policy => policy
.WithOrigins("http://localhost:5010")
.AllowAnyHeader()
.AllowAnyMethod());
app.UseClientSideBlazorFiles<Client.Program>();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapFallbackToClientSideBlazor<Client.Program>(@"index.html");
});
任何人都知道什么地方可能出问题了?
更新1
我现在在Chrome控制台中看到以下错误:
dotnet.js:1与'ws:// localhost:5000 / hubs / posts?id = 9Jxs0DhP924zgw_eIeE9Lg'的WebSocket连接失败:HTTP身份验证失败;没有有效的凭据可用
更新2
我从SignalR集线器中删除了[Authorize]
属性,现在它已连接。而且我可以将消息发送到中心。问题在于使用此属性是有原因的,因为我不希望人们可以订阅不适合他们的邮件]
更新3
仍然没有进展。正在考虑使用IdentityServer4将认证提取到单独的微服务。最后状态是我有以下启动例程:
就我而言,ASP.NET Core 2.2我有一个API,我希望可以使用该API中的SignalR连接到我的客户端应用程序。
我有用于的项目>
使用ASP.NET Core身份作为用户管理
为了使您的用户得到认证,您需要像这样实现IUserIdProvider
public class IdBasedUserIdProvider : IUserIdProvider { public string GetUserId(HubConnectionContext connection) { //TODO: Implement USERID Mapper Here //throw new NotImplementedException(); //return whatever you want to map/identify the user by here. Either ID/Email return connection.User.FindFirst("sub").Value; } }
通过此操作,我确保将ID /电子邮件发送到我从服务器或客户端调用的方法。尽管我总是可以在HubContext上使用.User,但是它可以正常工作。
在我想出的Web API Startup.cs文件中
Configuration.GetSection(“ AuthServer:DomainBaseUrl”)。Get()从配置文件中检索允许CORS的域列表。public void ConfigureServices(IServiceCollection services) { services.AddCors(cfg => { cfg.AddDefaultPolicy(policy => { policy.WithOrigins(Configuration.GetSection("AuthServer:DomainBaseUrl").Get<string[]>()) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials() .SetIsOriginAllowed((_) => true) .SetIsOriginAllowedToAllowWildcardSubdomains(); }); }); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, UserManager<AppUser> userManager, RoleManager<IdentityRole> roleManager){ app.UseCors(); }
NOTE
并且我在我的客户端应用程序COnfigureService方法中进行了此配置
services.AddCors(cfg => { cfg.AddDefaultPolicy(policy => { policy.AllowAnyHeader(); policy.AllowAnyMethod(); policy.SetIsOriginAllowed((host) => true); policy.AllowAnyOrigin(); }); });
希望这对您有所帮助。
最佳解决方案的确是Ismail Umer描述的,它使用诸如IdentityServer4之类的单独身份验证服务。并在所有其他服务中使用此服务。这是我将在下一次迭代中执行的操作。