J'ai résolu ce problème après ne pas avoir trouvé la solution sur Stackoverflow, donc je partage mon problème ici et la solution dans une réponse.
Après avoir activé une stratégie inter-domaines dans mon application .NET Core Web Api avec AddCors, elle ne fonctionne toujours pas à partir des navigateurs. En effet, les navigateurs, y compris Chrome et Firefox, enverront d'abord une demande OPTIONS et mon application répond simplement avec 204 Aucun contenu.
Ajoutez une classe middleware à votre projet pour gérer le verbe OPTIONS .
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
namespace Web.Middlewares
{
public class OptionsMiddleware
{
private readonly RequestDelegate _next;
public OptionsMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext context)
{
return BeginInvoke(context);
}
private Task BeginInvoke(HttpContext context)
{
if (context.Request.Method == "OPTIONS")
{
context.Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)context.Request.Headers["Origin"] });
context.Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
context.Response.Headers.Add("Access-Control-Allow-Methods", new[] { "GET, POST, PUT, DELETE, OPTIONS" });
context.Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
context.Response.StatusCode = 200;
return context.Response.WriteAsync("OK");
}
return _next.Invoke(context);
}
}
public static class OptionsMiddlewareExtensions
{
public static IApplicationBuilder UseOptions(this IApplicationBuilder builder)
{
return builder.UseMiddleware<OptionsMiddleware>();
}
}
}
Ajoutez ensuite app.UseOptions();
this comme première ligne dans Startup.cs dans la méthode Configure.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseOptions();
}
Je sais qu'il a été répondu. Il suffit de répondre avec les informations mises à jour. Cela aiderait donc les autres.
Son maintenant intégré dans le cadre de base asp.net.
Suivez simplement https://docs.Microsoft.com/en-us/aspnet/core/security/cors
et remplacer
app.UseCors(builder =>
builder.WithOrigins("http://example.com"));
avec
app.UseCors(builder =>
builder.WithOrigins("http://example.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials());
Cela a fonctionné pour moi:
Assurez-vous que ceci:
app.UseCors(builder => {
AllowAnyOrigin()
AllowAnyMethod()
AllowAnyHeader()
});
Se produit avant l'un de ces événements:
app.UseHttpsRedirection();
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseCookiePolicy();
N'oubliez pas que nous avons affaire à un "pipeline". Le cors doit être le premier.
-gimzani
Il n'y a pas besoin d'un middleware supplémentaire. Comme déjà mentionné ci-dessus, la seule chose nécessaire est la méthode OPTIONS autorisée dans la configuration Cors. Vous pouvez AllowAnyMethod comme suggéré ici: https://stackoverflow.com/a/55764660/1192191
Mais il est plus sûr de simplement autoriser les éléments spécifiques comme celui-ci:
app.UseCors(builder => builder
.WithOrigins("https://localhost", "https://production.company.com") /* list of environments that will access this api */
.WithMethods("GET", "OPTIONS") /* assuming your endpoint only supports GET */
.WithHeaders("Origin", "Authorization") /* headers apart of safe-list ones that you use */
);
Certains en-têtes sont toujours autorisés: https://developer.mozilla.org/en-US/docs/Glossary/CORS-safelisted_request_header
Je voulais autoriser cela pour une seule méthode, sans utiliser de middleware pour autoriser cela sur n'importe quelle méthode. Voici ce que j'ai fini de faire:
[HttpOptions("/find")]
public IActionResult FindOptions()
{
Response.Headers.Add("Access-Control-Allow-Origin", new[] { (string)Request.Headers["Origin"] });
Response.Headers.Add("Access-Control-Allow-Headers", new[] { "Origin, X-Requested-With, Content-Type, Accept" });
Response.Headers.Add("Access-Control-Allow-Methods", new[] { "POST, OPTIONS" }); // new[] { "GET, POST, PUT, DELETE, OPTIONS" }
Response.Headers.Add("Access-Control-Allow-Credentials", new[] { "true" });
return NoContent();
}
[HttpPost("/find")]
public async Task<IActionResult> FindOptions([FromForm]Find_POSTModel model)
{
AllowCrossOrigin();
// your code...
}
private void AllowCrossOrigin()
{
Uri Origin = null;
Uri.TryCreate(Request.Headers["Origin"].FirstOrDefault(), UriKind.Absolute, out Origin);
if (Origin != null && IsOriginAllowed(Origin))
Response.Headers.Add("Access-Control-Allow-Origin", $"{Origin.Scheme}://{Origin.Host}");
}
Et bien sûr, vous pouvez implémenter IsOriginAllowed
comme vous le souhaitez
private bool IsOriginAllowed(Uri Origin)
{
const string myDomain = "mydomain.com";
const string[] allowedDomains = new []{ "example.com", "sub.example.com" };
return
allowedDomains.Contains(Origin.Host)
|| Origin.Host.EndsWith($".{myDomain}");
}
Vous pouvez trouver plus de détails sur comment activer CORS pour POST requêtes sur un seul point de terminaison