asp.net signalr core 中的跨域请求不起作用?
Posted
技术标签:
【中文标题】asp.net signalr core 中的跨域请求不起作用?【英文标题】:Cross domain request in asp.net signalr core does not work? 【发布时间】:2019-08-05 03:34:53 【问题描述】:我正在使用 asp.net core 2.2 版本下的 asp.net core signalr 1.1.0。我想 为 Web 客户端和移动客户端发出跨域请求。 当我从 javascript 客户端发送请求时,此请求被阻止,并显示以下错误, (索引):1 从源 'https://localhost:44381' 访问 XMLHttpRequest 在 'https://localhost:44373/chatHub/negotiate?token=12' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:'Access-Control-Allow 的值-当请求的凭据模式为“包含”时,响应中的“来源”标头不能是通配符“*”。 XMLHttpRequest 发起的请求的凭证模式由 withCredentials 属性控制。
我的 Javascript 客户端代码
var connection = new signalR.HubConnectionBuilder().withUrl("https://localhost:44373/chatHub?token="+12).build();
Signalr核心服务启动类代码
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services.Configure<CookiePolicyOptions>(options =>
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
);
services.AddCors(options =>
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()/*WithOrigins("https://localhost:44381")*/
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
);
services.AddSignalR();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
//services.AddCors();
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
else
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
app.UseHttpsRedirection();
app.UseCors("CorsPolicy");
app.UseSignalR(routes =>
routes.MapHub<ChatHub>("/chatHub");
);
//app.UseStaticFiles();
//app.UseCookiePolicy();
app.UseMvc();
builder.AllowAnyOrigin() its not working
builder => builder.WithOrigins("https://localhost:44381") 它的工作,但这是特定于这个 origin , 我想做 AllowAnyOrigin()??
【问题讨论】:
您是否有任何商业案例希望允许任何来源?为您的原始配置设置一个 appsetting 字段应该不是问题。您还可以指定一个来源列表,这些来源也可以坚持到应用程序设置。这不适合你吗? 是的,我想为 web 和移动客户端使用 signalr 核心,所以对于移动客户端,我们不能给出任何来源?但是我怎样才能让它打开跨域连接。就像在 asp.net signalr 中一样 【参考方案1】:我是这样弄的
在顶部配置服务
services.AddCors();
在配置方法中
public class Startup
public Startup(IConfiguration configuration)
Configuration = configuration;
public IConfiguration Configuration get;
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
services
.AddDbContext<ChatContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.Configure<FormOptions>(options =>
options.MultipartBodyLengthLimit = 60000000;
);
services.AddMvc().AddJsonOptions(options =>
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
);
services.AddMvcCore()
.AddAuthorization()
.AddJsonOptions(options =>
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
);
var identityServerAuthOptions = Configuration.GetSection("Identity").Get<IdentityServerAuthenticationOptions>();
services.AddAuthentication("Bearer")
.AddIdentityServerAuthentication(options =>
options.Authority = identityServerAuthOptions.Authority;
options.RequireHttpsMetadata = identityServerAuthOptions.RequireHttpsMetadata;
options.ApiName = identityServerAuthOptions.ApiName;
);
var settings = new JsonSerializerSettings();
settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
settings.ContractResolver= new CamelCasePropertyNamesContractResolver();
services.AddSignalR()
.AddJsonProtocol(options =>
options.PayloadSerializerSettings = settings;
);
services.AddTransient<IUserService, UserService>();
services.AddCors();
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
//Data.AddData(app.ApplicationServices.GetService<ChatContext>());
app.Use(async (context, next) =>
if (string.IsNullOrWhiteSpace(context.Request.Headers["Authorization"]))
if (context.Request.QueryString.HasValue)
var token = context.Request.QueryString.Value.Split('&').SingleOrDefault(x => x.Contains("authorization"))?.Split('=')[1];
if (!string.IsNullOrWhiteSpace(token))
context.Request.Headers.Add("Authorization", new[] $"Bearer token" );
await next.Invoke();
);
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
// app.UseBrowserLink();
else
app.UseExceptionHandler("/Home/Error");
app.UseStaticFiles();
app.UseAuthentication();
app.UseCors(x => x.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().AllowCredentials());
app.UseSignalR(config =>
config.MapHub<UserHub>("/UsersHub");
);
app.UseMvc(routes =>
routes.MapRoute(
name: "default",
template: "controller=Home/action=Index/id?");
routes.MapSpaFallbackRoute("spa-fallback", new controller = "Home", action = "Index" );
);
app.UseCors(builder =>
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
);
完整的代码可以在这里找到。这过去对我来说很好用。不过最近没打开过
Github Repo
【讨论】:
嗨,npo,我使用了你的代码,但它不起作用,你能把完整的代码发给我吗。 我已经用你的代码更新了启动,但还是不行? @Ali 我刚刚更新了我的答案,包括对我有用的整个事情,还有一个指向整个项目所在的 github 的链接。希望有帮助 好的,谢谢,npo,你能完善你的 git lab 链接吗,它没有打开 谢谢指出,更新了答案。成功了吗?【参考方案2】:我发现您的代码存在两个问题。让我们一一解决。
允许整个应用程序的所有来源,即使您只需要 SignalR 连接。如果您只想为 signalR 端点应用 CORS 策略,请考虑以下代码
app.UseEndpoints(endpoints =>
endpoints.MapControllers();
endpoints.MapHub<UsersHub>("/UsersHub")
.RequireCors((policyBuilder) => policyBuilder
.WithOrigins("clientUrls")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
建议不要允许所有来源,但如果您有这样的用例,那么以下解决方法可以解决您的问题。这就是使用 .SetIsOriginAllowed(_ => true)
的技巧 .SetIsOriginAllowed(_ => true)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
如果您想了解更多信息,请查看guide 了解更多详情。
【讨论】:
以上是关于asp.net signalr core 中的跨域请求不起作用?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core SignalR 中的客户端生命周期事件