Ce que j'essaye de faire
J'ai une API Web principale ASP.Net Core hébergée sur un plan gratuit Azure (code source: https://github.com/killerrin/Portfolio-Backend ).
J'ai également un site Web client que je souhaite faire consommer cette API. L'application cliente ne sera pas hébergée sur Azure, mais sera plutôt hébergée sur des pages Github ou sur un autre service d'hébergement Web auquel j'ai accès. Pour cette raison, les noms de domaine ne s'aligneront pas.
En regardant cela, je dois activer CORS du côté de l'API Web, mais j'ai essayé à peu près tout pendant plusieurs heures maintenant et il refuse de fonctionner.
Comment j'ai la configuration du client C'est juste un simple client écrit en React.js. J'appelle les API via AJAX dans Jquery. Le site React fonctionne donc je sais que ce n'est pas ça. L'appel de l'API Jquery fonctionne comme je l'ai confirmé dans la tentative 1. Voici comment je passe les appels
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);
}
}
});
Ce que j'ai essayé
Tentative 1 - La `` bonne '' manière
https://docs.microsoft.com/en-us/aspnet/core/security/cors
J'ai suivi ce didacticiel sur le site Web de Microsoft jusqu'à un T, en essayant les 3 options pour l'activer globalement dans Startup.cs, en le configurant sur chaque contrôleur et en l'essayant à chaque action.
En suivant cette méthode, le Cross Domain fonctionne, mais uniquement sur une seule Action sur un seul contrôleur (POST sur le AccountController). Pour tout le reste, le Microsoft.AspNetCore.Cors
middleware refuse de définir les en-têtes.
J'ai installé Microsoft.AspNetCore.Cors
via NUGET et la version est1.1.2
Voici comment je l'ai configuré dans 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();
...
...
...
}
Comme vous pouvez le voir, je fais tout comme dit. J'ajoute Cors avant MVC les deux fois, et quand cela n'a pas fonctionné, j'ai essayé de mettre [EnableCors("MyPolicy")]
chaque contrôleur comme tel
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
Tentative 2 - Brute le forçant
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
Après plusieurs heures d'essais sur la tentative précédente, j'ai pensé que j'essaierais de le forcer brutalement en essayant de définir les en-têtes manuellement, les forçant à s'exécuter à chaque réponse. J'ai fait cela en suivant ce tutoriel sur la façon d'ajouter manuellement des en-têtes à chaque réponse.
Ce sont les en-têtes que j'ai ajoutés
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
Ce sont d'autres en-têtes que j'ai essayés qui ont échoué
.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")
Avec cette méthode, les en-têtes Cross Site sont correctement appliqués et ils apparaissent dans ma console développeur et dans Postman. Le problème est cependant que, même s'il réussit le Access-Control-Allow-Origin
test, le navigateur Web lance un ajustement sifflant (je crois)Access-Control-Allow-Headers
indiquant415 (Unsupported Media Type)
Donc, la méthode de la force brute ne fonctionne pas non plus
finalement
Quelqu'un a-t-il réussi à faire fonctionner cela et pourrait-il donner un coup de main, ou simplement être en mesure de me diriger dans la bonne direction?
ÉDITER
Donc, pour faire passer les appels d'API, j'ai dû arrêter d'utiliser JQuery et passer au XMLHttpRequest
format Pure Javascript .
Tentative 1
J'ai réussi à faire Microsoft.AspNetCore.Cors
fonctionner le en suivant la réponse de MindingData, sauf dans la Configure
méthode mettant l' app.UseCors
avant app.UseMvc
.
De plus, lorsqu'il est mélangé avec la solution API Javascript options.AllowAnyOrigin()
pour la prise en charge des caractères génériques, il a également commencé à fonctionner.
Tentative 2
J'ai donc réussi à faire fonctionner Attempt 2 (force brute) ... à la seule exception que le Wildcard pour Access-Control-Allow-Origin
ne fonctionne pas et que je dois donc définir manuellement les domaines qui y ont accès.
Ce n'est évidemment pas idéal puisque je veux juste que cette WebAPI soit largement ouverte à tout le monde, mais cela fonctionne au moins pour moi sur un site séparé, ce qui signifie que c'est un début
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)
problème, définissez un en-Content-Type
tête de demande surapplication/json
.