O que estou tentando fazer
Eu tenho uma API Web ASP.Net Core de back-end hospedada em um Plano Gratuito do Azure (código-fonte: https://github.com/killerrin/Portfolio-Backend ).
Eu também tenho um site do cliente que eu quero fazer consumir essa API. O Aplicativo Cliente não será hospedado no Azure, mas sim nas Páginas do Github ou em outro Serviço de Hospedagem da Web ao qual tenho acesso. Por esse motivo, os nomes de domínio não se alinham.
Analisando isso, preciso habilitar o CORS no lado da API da Web, no entanto, tentei quase tudo por várias horas e agora ele se recusa a trabalhar.
Como eu tenho a configuração do cliente É apenas um cliente simples escrito em React.js. Estou chamando as APIs através do AJAX no Jquery. O site React funciona, então eu sei que não é isso. A chamada da API do Jquery funciona como eu confirmei na tentativa 1. Aqui está como eu faço as chamadas
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);
}
}
});
O que eu tentei
Tentativa 1 - O caminho 'adequado'
https://docs.microsoft.com/en-us/aspnet/core/security/cors
Eu segui este tutorial no site da Microsoft até um T, tentando todas as 3 opções de ativá-lo globalmente no Startup.cs, configurando-o em todos os controladores e testando-o em todas as ações.
Seguindo esse método, o domínio cruzado funciona, mas apenas em uma única ação em um único controlador (POST para o AccountController). Para todo o resto, o Microsoft.AspNetCore.Cors
middleware se recusa a definir os cabeçalhos.
Eu instalei Microsoft.AspNetCore.Cors
através do NUGET e a versão é1.1.2
Aqui está como eu o configurei no 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 você pode ver, estou fazendo tudo o que foi dito. Eu adiciono Cors antes do MVC as duas vezes e, quando isso não funcionou, tentei colocar [EnableCors("MyPolicy")]
todos os controladores assim
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
Tentativa 2 - Brute Forçando-o
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
Depois de várias horas tentando a tentativa anterior, imaginei que tentaria forçá-la tentando definir os cabeçalhos manualmente, forçando-os a executar todas as respostas. Fiz isso seguindo este tutorial sobre como adicionar cabeçalhos manualmente a todas as respostas.
Estes são os cabeçalhos que adicionei
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
Estes são outros cabeçalhos que tentei que falharam
.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")
Com esse método, os cabeçalhos entre sites estão sendo aplicados corretamente e são exibidos no meu console do desenvolvedor e no Postman. O problema, no entanto, é que, enquanto passa na Access-Control-Allow-Origin
verificação, o navegador da web lança um chiado (acredito) Access-Control-Allow-Headers
afirmando415 (Unsupported Media Type)
Portanto, o método da força bruta também não funciona
Finalmente
Alguém conseguiu que isso funcionasse e poderia dar uma mãozinha ou apenas ser capaz de me apontar na direção certa?
EDITAR
Portanto, para obter as chamadas da API, tive que parar de usar o JQuery e mudar para o XMLHttpRequest
formato Javascript puro .
Tentativa 1
Eu consegui fazer o Microsoft.AspNetCore.Cors
trabalho seguindo a resposta de MindingData, exceto dentro do Configure
método colocando o app.UseCors
antes app.UseMvc
.
Além disso, quando combinado com a solução da API Javascript options.AllowAnyOrigin()
para suporte a caracteres curinga começou a funcionar também.
Tentativa 2
Então, eu consegui fazer com que a Tentativa 2 (força bruta) funcione ... com a única exceção de que o curinga Access-Control-Allow-Origin
não funciona e, como tal, tenho que definir manualmente os domínios que têm acesso a ela.
Obviamente, não é o ideal, pois eu só quero que essa WebAPI seja aberta a todos, mas pelo menos funciona para mim em um site separado, o que significa que é um começo
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"));
fonte
415 (Unsupported Media Type)
problema, defina umContent-Type
cabeçalho de solicitação comoapplication/json
.Respostas:
Como você possui uma política CORS muito simples (Permitir todas as solicitações do domínio XXX), não é necessário torná-la tão complicada. Tente fazer o seguinte primeiro (uma implementação muito básica do CORS).
Se você ainda não o fez, instale o pacote de nuget CORS.
No método ConfigureServices do seu startup.cs, adicione os serviços CORS.
Em seguida, no método Configure do seu startup.cs, adicione o seguinte:
Agora tente. As políticas são para quando você deseja políticas diferentes para ações diferentes (por exemplo, hosts diferentes ou cabeçalhos diferentes). Para seu exemplo simples, você realmente não precisa dele. Comece com este exemplo simples e ajuste conforme necessário a partir daí.
Outras leituras: http://dotnetcoretutorials.com/2017/01/03/enabling-cors-asp-net-core/
fonte
app.UseCors
APÓS `` app.UseMvc () `. Middlewares são executados na ordem em que são registradosoptions.DisableHttpsRequirement();
isso funcionasse. Parece que com as configurações https cors não estavam sendo aplicadas.No ConfigureServices, adicione
services.AddCors();
ANTES de services.AddMvc ();Adicionar UseCors no Configure
O ponto principal é que adicionar
app.UseCors
antesapp.UseMvc()
.Certifique-se de declarar a funcionalidade CORS antes do MVC, para que o middleware seja acionado antes que o pipeline do MVC obtenha o controle e finalize a solicitação.
Depois que o método acima funciona, você pode alterá-lo, configurar uma ORIGIN específica para aceitar chamadas da API e evitar deixar sua API tão aberta para qualquer pessoa
No método configure, diga ao CORS para usar a política que você acabou de criar:
Acabei de encontrar este artigo compacto sobre o assunto - https://dzone.com/articles/cors-in-net-core-net-core-security-part-vi
fonte
Configure()
a ordem não é realmente importante aqui dentroConfigureServices()
AllowCredentials()
comAllowAnyOrigin()
como acima. Para usar,AllowCredentials()
você precisa definirWithOrigins()
. docs.microsoft.com/en-us/aspnet/core/security/…Eu criei minha própria classe de middleware que funcionou para mim, acho que há algo errado com a classe de middleware .net core
e usado dessa maneira no startup.cs
fonte
if (!context.Request.Headers.ContainsKey(CorsConstants.Origin)) return this._next(context);
No meu caso, apenas o
get
pedido funciona bem de acordo com a resposta do MindingData. Para outros tipos de solicitação, você precisa escrever:Não esqueça de adicionar
.AllowAnyHeader()
fonte
Para expandir a user8266077 's resposta , eu descobri que eu ainda precisava de resposta opções de fornecimento de pedidos de pré-vôo em .NET Núcleo 2,1-visualização para o meu caso de uso:
e, em seguida, habilitou o middleware como em Startup.cs
fonte
app.Use<CorsMiddleware>();
await _next(context)
e definindo o código de status e a resposta manualmente, se isso acontecer. Eu também tive que adicionar "autorização" a Access-Control-Allow-Headers para que a solicitação de comprovação funcione ao fazer solicitações de reação que exijam autorização.fonte
Eu estava lutando com isso por dias.
Finalmente consegui trabalhar movendo
app.UseCors(CORS_POLICY);
para o TOPO deConfigure()
.Além disso:
Microsoft.AspNetCore.Cors
costumava ser um pacote NuGet necessário no .Net Core 2 e inferior; agora faz parte automaticamente do Microsoft.AspNetCore no .Net Core 3 e superior.builder.AllowAnyOrigin()
e.AllowCredentials()
CORS agora são mutuamente exclusivas no .Net Core 3 e superiorhttps
. Um URL http parecia dar um erro CORS, independentemente da configuração CORS do servidor .Net Core. Por exemplo,http://localhost:52774/api/Contacts
daria um erro de CORS; simplesmente alterando o URL parahttps://localhost:44333/api/Contacts
funcionado.Nota adicional :
fonte
Nenhum dos procedimentos acima ajudou e li o artigo que resolveu o problema.
Abaixo está o código.
e
e no topo do meu método de ação
fonte
app.UseCors()
) com[EnableCors()]
o mesmo aplicativo. Você deve usar um ou outro - mas não os dois: docs.microsoft.com/en-us/aspnet/core/security/… :Use the [EnableCors] attribute or middleware, not both in the same app.
tente adicionar
jQuery.support.cors = true;
antes da chamada do AjaxTambém pode ser que os dados que você está enviando para a API sejam instáveis,
tente adicionar a seguinte função JSON
em seus dados: objeto, altere-o para
fonte
A solução mais simples é adicionar
para Startup.cs.
fonte
Acho que se você usa seu próprio middleware CORS, precisa se certificar de que é realmente uma solicitação CORS , verificando o cabeçalho de origem .
fonte
Access-Control-Allow-Origin
cabeçalho não foi emitido pelo servidor. Na verdade, enviei solicitações via Postman sem oOrigin
cabeçalho. Isso salvou meu dia! (Ou pelo menos a minha manhã;))Com base no seu comentário na resposta do MindingData, isso não tem nada a ver com o seu CORS, está funcionando bem.
Sua ação do controlador está retornando os dados incorretos. HttpCode 415 significa "Tipo de mídia não suportado". Isso acontece quando você passa o formato errado para o controlador (ou seja, XML para um controlador que aceita apenas json) ou quando retorna um tipo errado (retorna Xml em um controlador declarado para retornar apenas xml).
Para mais tarde, verifique a existência do
[Produces("...")]
atributo em sua açãofonte
Para mim, não tinha nada a ver com o código que eu estava usando. Para o Azure, tivemos que entrar nas configurações do Serviço de Aplicativo, no menu lateral, na entrada "CORS". Lá, tive que adicionar o domínio do qual estava solicitando coisas. Depois que eu entendi, tudo foi mágico.
fonte
No launchSettings.json, em iisSettings, defina anonymousAuthentication como true:
Em Startup.cs, em ConfigureServices, antes de services.AddMvc, adicione:
e, em seguida, no método configure, antes de app.UseMvc () adicione:
fonte
Estou usando o .Net CORE 3.1 e passei anos batendo minha cabeça contra uma parede com essa quando percebi que meu código estava realmente funcionando, mas meu ambiente de depuração estava quebrado, então aqui estão duas dicas, se você estiver tentando solucionar o problema problema:
Se você estiver tentando registrar cabeçalhos de resposta usando o middleware ASP.NET, o cabeçalho "Access-Control-Allow-Origin" nunca será exibido, mesmo que esteja lá. Não sei como, mas parece ser adicionado fora do pipeline (no final, tive que usar o wireshark para vê-lo).
O .NET CORE não enviará o "Access-Control-Allow-Origin" na resposta, a menos que você tenha um cabeçalho "Origin" em sua solicitação. O Carteiro não definirá isso automaticamente, portanto você precisará adicioná-lo.
fonte
No meu caso, eu consertei com o UseCors antes do UserRouting.
fonte
.NET Core 3.1
Trabalhou para mim e como os documentos dizem para fazê-lo:
na classe Inicialização:
No método ConfigureServices ():
No método Configure ():
https://docs.microsoft.com/en-us/aspnet/core/security/cors?view=aspnetcore-3.1
fonte
Eu obtive a resposta do MindingData acima para funcionar, mas tive que usar o Microsoft.AspNet.Cors em vez do Microsoft.AspNetCore.Cors. Estou usando o projeto .NetCore Web Application API no Visual Studio 2019
fonte
o
permitirá que você execute o CORS com recursos internos, mas ele não processa a solicitação OPTIONS. Até agora, a melhor solução alternativa é criar um novo Middleware, conforme sugerido em uma postagem anterior. Verifique a resposta marcada como correta na seguinte postagem:
Ativar cabeçalho OPTIONS para CORS na API da Web do .NET Core
fonte
Maneira simples e fácil de fazê-lo.
Install-Package Microsoft.AspNetCore.Cors
app.UseCors(options => options.AllowAnyOrigin());
fonte
Aqui está o meu código:)
fonte
Aqui está como eu fiz isso.
Vejo que em algumas respostas eles estão definindo
app.UserCors("xxxPloicy")
e colocando[EnableCors("xxxPloicy")]
controladores. Você não precisa fazer as duas coisas.Aqui estão os passos.
Em Startup.cs, no ConfigureServices, adicione o seguinte código.
Se você deseja aplicar todo o projeto, adicione o seguinte código no método Configure em Startup.cs
Ou
Se você deseja adicioná-lo aos controladores específicos, adicione o código de ativação cors como mostrado abaixo.
Para mais informações: consulte este
fonte
Use um Atributo de Ação / Controlador personalizado para definir os cabeçalhos do CORS.
Exemplo:
Em seguida, no Web API Controller / Action:
fonte
Apenas para adicionar uma resposta aqui, se você estiver usando
app.UseHttpsRedirection()
e não estiver acessando a porta SSL, considere comentar isso.fonte
Eu estava usando o blazor webassembly como cliente e o asp.net web api core como back-end e também tive problemas com o cors.
Encontrei solução com estes códigos:
As primeiras linhas da API do núcleo da API do ASP.Net Startup.cs ConfigureServices e Configure são assim:
e meu método Configure:
mude
http://example.com
com o domínio do cliente ou endereço IPfonte
fonte