Cosa sto cercando di fare
Ho un'API Web ASP.Net Core back-end ospitata su un piano gratuito di Azure (codice sorgente: https://github.com/killerrin/Portfolio-Backend ).
Ho anche un sito Web del cliente che desidero far utilizzare quell'API. L'applicazione client non sarà ospitata su Azure, ma piuttosto sarà ospitata su Github Pages o su un altro servizio di hosting Web a cui ho accesso. Per questo motivo i nomi di dominio non si allineano.
In questo caso, devo abilitare CORS sul lato API Web, tuttavia ho provato praticamente tutto per diverse ore e si sta rifiutando di funzionare.
Come ho l'installazione del client È solo un semplice client scritto in React.js. Sto chiamando le API tramite AJAX in Jquery. Il sito React funziona, quindi so che non è quello. La chiamata API Jquery funziona come ho confermato nel tentativo 1. Ecco come effettuare le chiamate
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);
}
}
});
Quello che ho provato
Tentativo 1 - Il modo "corretto"
https://docs.microsoft.com/en-us/aspnet/core/security/cors
Ho seguito questo tutorial sul sito Web Microsoft fino a un T, provando tutte e 3 le opzioni per abilitarlo globalmente in Startup.cs, configurarlo su ogni controller e provarlo su ogni azione.
Seguendo questo metodo, Cross Domain funziona, ma solo su una singola azione su un singolo controller (da POST a AccountController). Per tutto il resto, il Microsoft.AspNetCore.Cors
middleware rifiuta di impostare le intestazioni.
Ho installato Microsoft.AspNetCore.Cors
tramite NUGET e la versione è1.1.2
Ecco come l'ho installato in 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();
...
...
...
}
Come puoi vedere, sto facendo tutto come detto. Aggiungo Cors prima di MVC entrambe le volte, e quando non ha funzionato ho provato a mettere [EnableCors("MyPolicy")]
su ogni controller così
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
Tentativo 2 - Bruto forzandolo
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
Dopo diverse ore di tentativi sul tentativo precedente, ho pensato che avrei provato a potenziarlo provando a impostare manualmente le intestazioni, costringendole a correre su ogni risposta. L'ho fatto seguendo questo tutorial su come aggiungere manualmente le intestazioni ad ogni risposta.
Queste sono le intestazioni che ho aggiunto
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
Queste sono altre intestazioni che ho provato e che hanno fallito
.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 questo metodo, le intestazioni Cross Site vengono correttamente applicate e vengono visualizzate nella mia console di sviluppo e in Postman. Il problema tuttavia è che mentre passa il Access-Control-Allow-Origin
controllo, il webbrowser lancia un sibilante adattamento (credo) Access-Control-Allow-Headers
affermando415 (Unsupported Media Type)
Quindi anche il metodo della forza bruta non funziona
Finalmente
Qualcuno ha ottenuto che funzioni e potrebbe dare una mano o essere in grado di indicarmi la giusta direzione?
MODIFICARE
Quindi, per far passare le chiamate API, ho dovuto smettere di usare JQuery e passare a un XMLHttpRequest
formato Javascript puro .
Tentativo 1
Sono riuscito a farlo Microsoft.AspNetCore.Cors
funzionare seguendo la risposta di MindingData, ad eccezione del Configure
metodo che app.UseCors
precede app.UseMvc
.
Inoltre, quando combinato con la soluzione API Javascript options.AllowAnyOrigin()
per il supporto con caratteri jolly ha iniziato a funzionare anche.
Tentativo 2
Quindi sono riuscito a far funzionare Attempt 2 (forzandolo bruto) ... con l'unica eccezione per cui Wildcard Access-Control-Allow-Origin
non funziona e come tale devo impostare manualmente i domini che hanno accesso ad esso.
Ovviamente non è l'ideale poiché voglio solo che questa WebAPI sia aperta a tutti, ma almeno funziona per me su un sito separato, il che significa che è un inizio
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, impostaContent-Type
un'intestazione di richiesta suapplication/json
.