Was ich versuche zu tun
Ich habe eine Backend-ASP.Net Core-Web-API, die auf einem Azure Free Plan gehostet wird (Quellcode: https://github.com/killerrin/Portfolio-Backend ).
Ich habe auch eine Client-Website, auf der diese API verwendet werden soll. Die Clientanwendung wird nicht auf Azure gehostet, sondern auf Github Pages oder einem anderen Webhostingdienst, auf den ich Zugriff habe. Aus diesem Grund werden die Domainnamen nicht ausgerichtet.
In diesem Zusammenhang muss ich CORS auf der Web-API-Seite aktivieren. Ich habe jedoch seit einigen Stunden so gut wie alles ausprobiert und es weigert sich zu funktionieren.
Wie ich das Client-Setup habe Es ist nur ein einfacher Client, der in React.js geschrieben ist. Ich rufe die APIs über AJAX in Jquery auf. Die React-Site funktioniert, also weiß ich, dass es das nicht ist. Der Jquery-API-Aufruf funktioniert wie in Versuch 1 bestätigt. So tätige ich die Aufrufe
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);
}
}
});
Was ich versucht habe
Versuch 1 - Der "richtige" Weg
https://docs.microsoft.com/en-us/aspnet/core/security/cors
Ich habe dieses Tutorial auf der Microsoft-Website bis zu einem T befolgt und alle drei Optionen ausprobiert, um es global in Startup.cs zu aktivieren, es auf jedem Controller einzurichten und es bei jeder Aktion zu versuchen.
Nach dieser Methode funktioniert die domänenübergreifende Funktion, jedoch nur für eine einzelne Aktion auf einem einzelnen Controller (POST an den AccountController). Für alles andere Microsoft.AspNetCore.Cors
weigert sich die Middleware, die Header zu setzen.
Ich habe Microsoft.AspNetCore.Cors
über NUGET installiert und die Version ist1.1.2
Hier ist, wie ich es in Startup.cs eingerichtet habe
// 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();
...
...
...
}
Wie Sie sehen können, mache ich alles wie gesagt. Ich füge beide Male Cors vor MVC hinzu, und als das nicht funktionierte, versuchte ich, [EnableCors("MyPolicy")]
jeden Controller so einzuschalten
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
Versuch 2 - Brute Forcing it
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
Nachdem ich den vorherigen Versuch mehrere Stunden lang ausprobiert hatte, dachte ich, ich würde versuchen, ihn zu erzwingen, indem ich versuchte, die Header manuell festzulegen, sodass sie bei jeder Antwort ausgeführt werden mussten. Ich habe dies nach diesem Tutorial getan, wie man jeder Antwort manuell Header hinzufügt.
Dies sind die Header, die ich hinzugefügt habe
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
Dies sind andere Header, die ich ausprobiert habe und die fehlgeschlagen sind
.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")
Bei dieser Methode werden die Cross Site-Header ordnungsgemäß angewendet und in meiner Entwicklerkonsole und in Postman angezeigt. Das Problem ist jedoch, dass Access-Control-Allow-Origin
der Webbrowser , während er die Prüfung besteht, einen zischenden Anfall auf (glaube ich) Access-Control-Allow-Headers
Aussage macht415 (Unsupported Media Type)
Die Brute-Force-Methode funktioniert also auch nicht
Schließlich
Hat jemand dies zum Laufen gebracht und könnte helfen oder mich einfach in die richtige Richtung weisen?
BEARBEITEN
Damit die API-Aufrufe ausgeführt werden konnten, musste ich JQuery nicht mehr verwenden und zu einem Pure Javascript- XMLHttpRequest
Format wechseln .
Versuch 1
Ich schaffte es das zu bekommen , Microsoft.AspNetCore.Cors
um die Arbeit von MindingData Antwort folgen, es sei denn innerhalb der Configure
Methode der Umsetzung app.UseCors
vor app.UseMvc
.
Darüber hinaus begann das Mischen mit der Javascript-API-Lösung options.AllowAnyOrigin()
für die Platzhalterunterstützung ebenfalls zu funktionieren.
Versuch 2
Ich habe es also geschafft, Versuch 2 (Brute Forcing It) zum Laufen zu bringen ... mit der einzigen Ausnahme, dass der Platzhalter für Access-Control-Allow-Origin
nicht funktioniert, und als solche muss ich die Domänen, die Zugriff darauf haben, manuell festlegen.
Es ist offensichtlich nicht ideal, da ich nur möchte, dass dieses WebAPI für alle zugänglich ist, aber es funktioniert zumindest für mich auf einer separaten Site, was bedeutet, dass es ein Anfang ist
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)
Setzen Sie für Ihr Problem einenContent-Type
Anforderungsheader aufapplication/json
.