I am trying to use the Azure SignalR Service in a web app that only contains a hub class. When I try to access from another domain to the hub I get the following error
"Access to XMLHttpRequest at 'https://*/genericSocketHub/negotiate' from origin 'https://localhost:44303' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.".
In the startup.cs class of my project I have:
` public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc()
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver())
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddCors(o => o.AddPolicy("Policy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
}));
services.AddSignalR().AddAzureSignalR(Configuration.GetConnectionString("AzureSignalRConnectionString")).AddJsonProtocol(options => options.PayloadSerializerSettings = new Newtonsoft.Json.JsonSerializerSettings() { ContractResolver = new DefaultContractResolver()});
services.AddSingleton(Configuration);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, Microsoft.AspNetCore.Hosting.IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors("Policy");
app.UseAzureSignalR(routes =>
{
routes.MapHub<GenericSocketHub>("/genericSocketHub");
});
app.UseMvc();
}
}`
Without using Azure SignalR Service I didn't have any CORS issues
Try adding .WithOrigins("[THE_DOMAIN_TO_UNBLOCK]"); to your policy:
services.AddCors(o => o.AddPolicy("Policy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
.WithOrigins("[THE_DOMAIN_TO_UNBLOCK]");
}));
Also make sure that you have the latest version of Microsoft.Asure.SignalR installed on the server along with the latest #aspnet/signalr installed on the client.
NOTE The signalr npm package is not compatible with Azure SignalR. I learned this the hard way..
The following worked for my setup which is Angular7, .NET CORE 2.1 and Azure SignalR. My setup looks like this:
ConfigureServices
// Add CORS
services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins",
builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowCredentials()
.AllowAnyMethod()
.WithOrigins("http://localhost:4200");
});
});
// Add Azure SignalR
services.AddSignalR().AddAzureSignalR();
Configure
app.UseCors("AllowAllOrigins");
app.UseAzureSignalR(routes =>
{
routes.MapHub<NextMatchHub>("/nextmatch");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "api/{controller=Home}/{action=Index}/{id?}");
});
NOTE Make sure that the various implementations are added in the same order as my example shows above. I cannot explain why it is sensitive about the order but this was also an issue on my end.
Related
I have a global CORS policy defined like this
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// global cors policy
app.UseCors("MyPolicy");
}
I must specify the global policy because I am using SignalR.
The policy allows the domain of the website.
In addition, I need to provide a limited number of endpoints for partners that have many different domains.
How do I allow a specific controller to be accessed from any origin (exclude from global policy and add custom policy)?
In StartUp.cs you could configure cors in ConfigureService
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
});
}
Then in Configure function you could configure the cors per mapped SignlR hub:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseCors();
...
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
//Map each hub and ad RequireCors per hub
endpoints.MapHub<EchoHub>("echo")
.RequireCors(MyAllowSpecificOrigins);
endpoints.MapRazorPages();
});
}
I am trying to make an API Call on my C# Web API from my Angular Frontend.
I have tried it by HTTP and HTTPS.
HTTP: I am getting a CORS exception
HTTPS: I am getting a CONNECTION CLOSED EXCEPTION
I also have tried it via Postman and it worked so the Backend should not be the Problem.
I am using the Angular HTTP Client.
in your Startup.cs file in the ConfigureServices there must exist the following code
public void ConfigureServices(IServiceCollection services) method.
{
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder => builder
.WithOrigins("http://localhost:4200", "YOUR_REQUEST_ORIGIN_URI")
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()));
}
Cors is security of browser, without cors configuration in api work it on postman, postman is not a web browser.
Try adding Cors configuration, on your api
[AspNet Web API]
Install package
Install-Package Microsoft.AspNet.WebApi.Cors
Edit WebApiConfig file, in App_Start/WebApiConfig.cs
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//change www.example.com for you domain, like localhost
var cors = new EnableCorsAttribute("www.example.com", "*", "*");
config.EnableCors(cors);
}
}
[.Net Core]
Edit Startup.cs and add CORS middleware and service
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
//change www.example.com for you domain, like localhost
builder.WithOrigins("http://example.com");
});
});
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
References
AspNet WebApi
.Net Core
I would like to enable by EnableCors attribute my own "MyPolicy" for one controller and for the others I would like to use default policy. So in my configure services method I write
services.AddCors(options =>
{
options.AddPolicy(name: "MyPolicy",
builder => builder
.WithOrigins("http://localhost:3000")
.AllowCredentials()
.AllowAnyMethod()
.AllowAnyHeader());
options.AddDefaultPolicy(
builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader());
});
and than in Configure method I just call:
app.UseCors();
it does not work as I expected. It's only define DefaultPolicy and the only way to use "MyPolicy" is to use them as:
app.UseCors("MyPolicy");
But in this case default policy does not work.
Is it possible to define own policies by AddPolicy and default policy by AddDefaultPolicy.
If you would like to use many own policies and default policy the solution is to define in configureservices:
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://example.com",
"http://www.contoso.com");
});
options.AddPolicy("AnotherPolicy",
builder =>
{
builder.WithOrigins("http://www.contoso.com")
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
and use policies through EnableCorsAttribute like this:
// GET api/values
[EnableCors("AnotherPolicy")]
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return new string[] { "green widget", "red widget" };
}
. In this case do not call UseCors method of app IApplicationBuilder object in configure method startup class.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
//Do not use this method:
//app.UseCors();
app.UseHttpsRedirection();
app.UseMvc();
}
I have followed the guidelines listed in the Microsoft article: Enable Cross-Origin Requests (CORS) in ASP.NET Core and I am still unable to access the API from the local vue website or PostMan. Any suggestions?
Here is what is defined in AllowedHosts:
"AllowedHosts": "http://localhost;http://localhost:8080"
Here is the startup class:
using App.Core.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace App.Core
{
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<ImportContext>((builder) =>
{
builder.UseSqlServer(Configuration.GetConnectionString("ParsingAppDb"));
});
services.AddDbContext<CodeAdminContext>((builder) =>
{
builder.UseSqlServer(Configuration.GetConnectionString("ParsingAppDb"));
});
services.AddScoped(typeof(IImportContext), typeof(ImportContext));
services.AddScoped(typeof(ICodeAdminContext), typeof(CodeAdminContext));
services.AddTransient(typeof(Logic.IImporter), typeof(Logic.Importer));
services.AddTransient(typeof(Logic.I2964Procssor), typeof(Logic.Processor_2964));
services.AddTransient(typeof(Logic.I2965Procssor), typeof(Logic.Processor_2965));
var allowedHosts = Configuration.GetValue(typeof(string), "AllowedHosts") as string;
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
if (allowedHosts == null || allowedHosts == "*")
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
return;
}
string[] hosts;
if (allowedHosts.Contains(';'))
hosts = allowedHosts.Split(';');
else
{
hosts = new string[1];
hosts[0] = allowedHosts;
}
builder.WithOrigins(hosts)
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials();
});
}); services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
Even using fiddler does not show anything helpful, just the denied call. Conversely if I set it to any origin I can get PostMan to work but the vue website then returns that no Accept-Control was set.
Update: And I already have the Microsoft.AspNetCore.Cors package installed.
I found the problem. It is the configuration value:
"AllowedHosts": "http://localhost;http://localhost:8080"
Apparently this value is used in another way, creating a separate Cors section and placing the allowed cors hosts there and then changing the AllowedHosts value back to * fixed the issue.
I have just created a default dotnet core 3.0 API project with the basic weather forecast API. I wanted to get CORS working before I did anything else with the project.
In startup i have the following code....
private readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddControllers();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseCors(MyAllowSpecificOrigins);
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
As you can see, I am not doing anything special or seemingly incorrect. This is directly from the MSDN documentation....
https://learn.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.0
The problem is that when sending requests through both the browser and postman, There are none of the expected headers in the given responses.
I have googled the crap out of this and have not got anywhere. Am i missing something? could it be environmental? has it changed from a previous version of core?