I have an application up and running on Azure and I'm trying to post data from an ESP8266 to https://myApplication.azurewebservices.net/api/call. But I'm not getting anywhere. The ESP8266 seems to have trouble handling HTTPS and so I thought I would try to enable HTTP POST requests.
My startup class looks like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyDatabase")));
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();
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)
{
app.UseCors(options => options.AllowAnyHeader().AllowAnyOrigin().AllowAnyMethod());
app.UseDeveloperExceptionPage();
app.UseAuthentication();
app.UseMvcWithDefaultRoute();
}
I thought that by allowing anyheaders, anyorigin, and anymethod would allow me to post HTTP requests.
But trying it in Postman still returns a 404 not found if I do http://myApplication.azurewebservices.net/api/call, but it does work if I use https://.
How can I make my application accept the exact same request but with HTTP instead of HTTPS?
You need to specifically enable HTTP requests for your App Service in the Azure Portal.
Dashboard > App Service > Custom Domains > disable "HTTPS only"
Related
I am using .NET Framework Web API, and I need to verify the API calls are from my hosted portal end.
Is there any method to validate request and block requests?
I used CORS to validate, and I don't know if that is the best practice to verify.
Your question is not clear. if you want to verify the API calls from your hosted portal and block other domain the best way is to use the Cross Origin Resource Sharing (CORS):
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: AllowPortalDomain,
policy =>
{
policy.WithOrigins("http://PortalDomain.com");
});
});
...
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
...
app.UseCors(AllowPortalDomain);
...
}
You can enable Cross-Origin Requests per controller or action:
[EnableCors("AllowPortalDomain")]
[HttpPost]
public IActionResult yourAPI(){...}
for more information see this link CORS
hope this helps!
So I 've made a web app using Vue, and I'm using ASP.NET Web App (.NET 5) for the backend.
When I run the Web API locally on localhost:44393 it works just great making POST & GET requests from the client that's running locally.
I then go to click "Publish" to send the files over to where I'm hosting.
At this point I change the URL that the client uses to make requests to https://api.mywebsite.com which is the same website as the one that was running locally since I published it now.
(it makes these requests using fetch so it would be fetch("https://api.mywebsite.com/TheController/AddServer" for instance)
This is where it gets weird because when I make a post request to register or sign in, it works just fine, but as soon as I go to "Add post" which is a form that posts to a different endpoint on the API, I get this error.
Access to fetch at 'https://api.mywebsite.com/TheController/AddPost'
from origin 'https://mywebsite.com' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the
requested resource. If an opaque response serves your needs, set the
request's mode to 'no-cors' to fetch the resource with CORS disabled.
And that doesn't happen when I run the web API locally. Why is it that it only occurs after I publish the files to my host and use the actual domain?
(I tried making the same request from the client when it's running locally too but it gives the exact same exception)
I switched out the domain name in the question to mywebsite.com because I don't want to share it.
Here is my ConfigurationServices
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy(name: MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("https://mywebsite.com",
"http://localhost:8080",
"https://mywebsite.com/add")
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
...
And the Configure
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "mcraftserverapi v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors(MyAllowSpecificOrigins);
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapControllers()
.RequireCors(MyAllowSpecificOrigins);
});
}
you have to remove
builder.WithOrigins("https://mywebsite.com",
"http://localhost:8080"
)
or
.AllowAnyOrigin()
you can't use them together
I'm using Visual Studio to publish an ASP.NET Core 2.1 app to AWS Lambda (serverless). No matter what I've tried I cannot get CORS to work.
All I really want to do is add the header access-control-allow-origin globally to my web app.
Has anyone ever successfully added headers to an ASP.NET Core 2.1 Serverless app?
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// AddCors must be before AddMvc
services.AddCors();
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// UseCors must be before UseMvc
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
);
// Also tried this
// app.UseCors(
// o => o.WithOrigins("http://example.com").AllowAnyMethod()
//);
app.UseMvc();
}
No CORS headers are added to my pages. I'm using Chrome dev tools to inspect my headers. I should see them on the homepage (for example) correct?
Any ideas? I'm dyin over here. Thanks!
EDIT
This application only uses API Gateway, Lambda and a few other services. It's great because I'm only charged when someone hits my app. There are no hourly charges. No EC2 or ELB which is amazing.
Also, I almost added this to my original post. The article #sturcotte06 references has a gotcha.
The API Gateway (automatically generated) uses the ANY method in a proxy integration. The above article says this...
Important
When applying the above instructions to the ANY method in a proxy integration, any applicable CORS headers will not be set. Instead, your backend must return the applicable CORS headers, such as Access-Control-Allow-Origin.
Ugh! So it's saying I must do this on the backend (Startup.cs right?) which is exactly what seems to get ignored when published.
For whatever reason app.UseCors does not work in my scenario. However, app.Use does...
app.Use((context, next) =>
{
context.Response.Headers["Access-Control-Allow-Origin"] = "https://example.com";
return next.Invoke();
});
app.UseMvc();
I am trying to enable CORS within my ASP.NET Core API and allow passing cookies from my client application (Angular 6). However, whenever I attempt to hit an endpoint through my Angular application, I am receiving the following error:
Response to preflight request doesn't pass access control check: The
value of the 'Access-Control-Allow-Origin' header in the response must
not be the wildcard '*' when the request's credentials mode is
'include'
Within my Startup.cs file, I have CORS enabled under ConfigureServices like:
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials()
.WithOrigins("http://localhost:4200"));
});
and under Configure:
app.UseCors("CorsPolicy");
In my Angular 6 application, I am calling the endpoint with a token like this:
this.http.get<T>(url, { headers: new HttpHeaders({ 'X-XSRF-TOKEN': token}), withCredentials: true });
The error is confusing because I am explicitly setting the allowed origins in .WithOrigins() within my .AddCors function, yet it's still saying there is only a wild card.
If this is hosted on Azure. Check the CORS settings in Azure AppService. The configurations there will override any other Cors configuration even in the .net core middleware.
within
public void ConfigureServices(IServiceCollection services)
after
services.AddMvc()
try
services.AddCors(options =>
{
options.AddPolicy("CorsPolicy",
builder => builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
});
then within
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
try
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseCors("CorsPolicy");
Once you do the above to your asp.net core api, you can test as shown below
if you can get the options request to the api to respond with the above headers, you have resolved the api CORS issue, then its time to move onto the angular 6 code.
The Enforcing SSL in a ASP.NET Core App guide on MSDN, tells me to add the following code to my Configure method in the Startup class, in order to redirect all http request to https:
var options = new RewriteOptions()
.AddRedirectToHttps();
app.UseRewriter(options);
Having added the code in the correct place, and testing a http request in debug mode, I get a connection reset error in chrome:
This site can’t be reached
The connection was reset.
Try:
Checking the connection
Checking the proxy and the firewall
Running Windows Network Diagnostics
ERR_CONNECTION_RESET
I'm trying to access the same URL (including port.. which I think is where I might be going wrong?) that I would if I was using https... I.E, I'm typing http://localhost:44376 instead of https://localhost:44376 into my address bar.
A slimmed down version of my Configuration method looks like this:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
var options = new RewriteOptions()
.AddRedirectToHttps();
app.UseRewriter(options);
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
app.UseBrowserLink();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseIdentity();
app.UseFacebookAuthentication(new FacebookOptions()
{
AppId = Configuration["Authentication_FacebookAppId"],
AppSecret = Configuration["Authentication_FacebookAppSecret"]
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
As this github post confirms, I was on the right lines thinking it was probably the port that was causing the issue. (Essentially, you can't listen for http and https requests on the same port.)
The fix for me was actually three-fold:
Firstly, you need to be careful how your running your app in development. When running visual studio on windows, the default is to startup using IIS / IIS Express. This causes a problem because it uses the application url defined in the project settings, rather than the urls we try to pass to kestrel via the startup class. (It's the applicationUrl defined in the iisSettings section of launchSettings.json)
If you expand the drop down on the start button inside Visual Studio, you should see an option with your project name, this starts your application using Kestrel via the dotnet CLI.
Secondly, you need to define two url's for kestrel to listen on, one for http and the other for https. This is done by simply passing in two url's, with different ports to the UseUrls() method in main():
var host = new WebHostBuilder()
.UseKestrel(options => {
options.UseHttps(certFile, certPass);
})
.UseContentRoot(Directory.GetCurrentDirectory())
.UseUrls("https://*:44388", "http://*:8080")
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
Finally, if your not using the default https port (443), you'll need to specify which port you want kestrel to redirect http request too. To do this, simply overload the AddRedirectToHttps() method, by passing in a status code and the port your wanting to redirect too. I've used the status code 301 to permanently redirect to https.
var options = new RewriteOptions()
.AddRedirectToHttps(301, 44388);
I had the similar issue with the usage of .AddRedirectToHttps(). But I found out that it might not set the port correctly to the default SSL port 443.
Use AddRedirectToHttpsPermanent() instead!, because it will default the port to 443.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// Redirects all HTTP requests to HTTPS
if (env.IsProduction())
{
app.UseRewriter(new RewriteOptions()
.AddRedirectToHttpsPermanent());
}
....
}