Lo que estoy tratando de hacer
Tengo una API web ASP.Net Core de back-end alojada en un plan gratuito de Azure (código fuente: https://github.com/killerrin/Portfolio-Backend ).
También tengo un sitio web de cliente que quiero hacer que consuma esa API. La aplicación de cliente no se alojará en Azure, sino que se alojará en páginas de Github u otro servicio de alojamiento web al que tenga acceso. Debido a esto, los nombres de dominio no se alinearán.
Al investigar esto, necesito habilitar CORS en el lado de la API web, sin embargo, he intentado casi todo durante varias horas y se niega a funcionar.
Cómo tengo la configuración del cliente Es solo un cliente simple escrito en React.js. Estoy llamando a las API a través de AJAX en Jquery. El sitio React funciona, así que sé que no es eso. La llamada a la API de Jquery funciona como lo confirmé en el intento 1. Así es como hago las llamadas
var apiUrl = "http://andrewgodfroyportfolioapi.azurewebsites.net/api/Authentication";
//alert(username + "|" + password + "|" + apiUrl);
$.ajax({
url: apiUrl,
type: "POST",
data: {
username: username,
password: password
},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
var authenticatedUser = JSON.parse(response);
//alert("Data Loaded: " + authenticatedUser);
if (onComplete != null) {
onComplete(authenticatedUser);
}
},
error: function (xhr, status, error) {
//alert(xhr.responseText);
if (onComplete != null) {
onComplete(xhr.responseText);
}
}
});
Lo que he intentado
Intento 1 - La forma 'adecuada'
https://docs.microsoft.com/en-us/aspnet/core/security/cors
He seguido este tutorial en el sitio web de Microsoft hasta una T, probando las 3 opciones de habilitarlo globalmente en Startup.cs, configurándolo en cada controlador y probándolo en cada acción.
Siguiendo este método, Cross Domain funciona, pero solo en una sola Acción en un solo controlador (POST al AccountController). Para todo lo demás, el Microsoft.AspNetCore.Cors
middleware se niega a configurar los encabezados.
Instalé a Microsoft.AspNetCore.Cors
través de NUGET y la versión es1.1.2
Así es como lo configuro en Startup.cs
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
// Add Cors
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
{
builder.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader();
}));
// Add framework services.
services.AddMvc();
services.Configure<MvcOptions>(options =>
{
options.Filters.Add(new CorsAuthorizationFilterFactory("MyPolicy"));
});
...
...
...
}
// This method gets called by the runtime. Use this method to configure
//the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env,
ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole(Configuration.GetSection("Logging"));
loggerFactory.AddDebug();
// Enable Cors
app.UseCors("MyPolicy");
//app.UseMvcWithDefaultRoute();
app.UseMvc();
...
...
...
}
Como puede ver, estoy haciendo todo lo que me dijeron. Agregué Cors antes de MVC las dos veces, y cuando eso no funcionó, intenté poner [EnableCors("MyPolicy")]
cada controlador como tal
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
Intento 2 - Brute forzándolo
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
Después de varias horas de intentar el intento anterior, pensé que trataría de aplicar una fuerza bruta al tratar de configurar los encabezados manualmente, obligándolos a ejecutarse en cada respuesta. Hice esto siguiendo este tutorial sobre cómo agregar encabezados manualmente a cada respuesta.
Estos son los encabezados que agregué
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
Estos son otros encabezados que probé que fallaron
.AddCustomHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "content-type, accept, X-PINGOTHER")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Host, User-Agent, Accept, Accept: application/json, application/json, Accept-Language, Accept-Encoding, Access-Control-Request-Method, Access-Control-Request-Headers, Origin, Connection, Content-Type, Content-Type: application/json, Authorization, Connection, Origin, Referer")
Con este método, los encabezados Cross Site se aplican correctamente y se muestran en mi consola de desarrollador y en Postman. Sin embargo, el problema es que mientras pasa el Access-Control-Allow-Origin
cheque, el navegador web lanza un ataque siseante (creo) Access-Control-Allow-Headers
indicando415 (Unsupported Media Type)
Entonces el método de fuerza bruta tampoco funciona
Finalmente
¿Alguien ha conseguido que esto funcione y pueda echar una mano, o simplemente poder señalarme en la dirección correcta?
EDITAR
Entonces, para que las llamadas a la API se procesen, tuve que dejar de usar JQuery y cambiar a un XMLHttpRequest
formato Javascript puro .
Intento 1
Me las arreglé para Microsoft.AspNetCore.Cors
que funcionara siguiendo la respuesta de MindingData, excepto dentro del Configure
Método que pone el app.UseCors
antes app.UseMvc
.
Además, cuando se combina con la Solución API de Javascript options.AllowAnyOrigin()
para el soporte comodín, comenzó a funcionar también.
Intento 2
Así que he logrado que el Intento 2 (fuerza bruta) funcione ... con la única excepción de que el comodín Access-Control-Allow-Origin
no funciona y, como tal, tengo que configurar manualmente los dominios que tienen acceso a él.
Obviamente no es ideal, ya que solo quiero que este WebAPI esté abierto para todos, pero al menos funciona para mí en un sitio separado, lo que significa que es un comienzo
app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
.AddDefaultSecurePolicy()
.AddCustomHeader("Access-Control-Allow-Origin", "http://localhost:3000")
.AddCustomHeader("Access-Control-Allow-Methods", "OPTIONS, GET, POST, PUT, PATCH, DELETE")
.AddCustomHeader("Access-Control-Allow-Headers", "X-PINGOTHER, Content-Type, Authorization"));
415 (Unsupported Media Type)
problema, establezca unContent-Type
encabezado de solicitud enapplication/json
.