我正在尝试做什么
我有一个托管在 Azure 免费计划上的后端 ASP.Net Core Web API (在.Net Core中添加默认安全标头 https://github.com/killerrin/Portfolio-Backend).
我还有一个客户端网站,我想让它使用该 API。客户端应用程序不会托管在 Azure 上,而是托管在 Github Pages 或我有权访问的其他 Web 托管服务上。因此,域名不会排列。
考虑到这一点,我需要在 Web API 端启用 CORS,但是我已经尝试了几乎所有方法几个小时,但它拒绝工作。
我如何进行客户端设置它只是一个用 React.js 编写的简单客户端。我通过 Jquery 中的 AJAX 调用 API。 React 网站可以正常工作,所以我知道事实并非如此。 Jquery API 调用的工作原理正如我在尝试 1 中所确认的那样。以下是我进行调用的方式
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);
}
}
});
我尝试过的
尝试 1 - “正确”的方式
https://learn.microsoft.com/en-us/aspnet/core/security/cors https://learn.microsoft.com/en-us/aspnet/core/security/cors
我已经按照 Microsoft 网站上的本教程进行了彻底的操作,尝试了在 Startup.cs 中全局启用它的所有 3 个选项,在每个控制器上进行设置并在每个操作上尝试它。
按照此方法,跨域可以工作,但仅限于单个控制器上的单个操作(POST 到 AccountController)。对于其他一切,Microsoft.AspNetCore.Cors
中间件拒绝设置标头。
我安装了Microsoft.AspNetCore.Cors
通过 NUGET 版本是1.1.2
这是我在 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();
...
...
...
}
正如你所看到的,我正在按照指示做一切。我两次在 MVC 之前添加 Cors,当这不起作用时,我尝试将[EnableCors("MyPolicy")]
在每个控制器上都是如此
[Route("api/[controller]")]
[EnableCors("MyPolicy")]
public class AdminController : Controller
尝试 2 - 暴力破解
https://andrewlock.net/adding-default-security-headers-in-asp-net-core/ https://andrewlock.net/adding-default-security-headers-in-asp-net-core/
经过几个小时的上一次尝试后,我想我会尝试通过手动设置标头来暴力破解它,强制它们在每个响应上运行。我按照本教程执行此操作,了解如何手动向每个响应添加标头。
这些是我添加的标题
.AddCustomHeader("Access-Control-Allow-Origin", "*")
.AddCustomHeader("Access-Control-Allow-Methods", "*")
.AddCustomHeader("Access-Control-Allow-Headers", "*")
.AddCustomHeader("Access-Control-Max-Age", "86400")
这些是我尝试过但失败的其他标头
.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")
通过这种方法,跨站点标头被正确应用,并且它们显示在我的开发人员控制台和 Postman 中。然而问题是,虽然它通过了Access-Control-Allow-Origin
检查一下,网络浏览器发出嘶嘶声(我相信)Access-Control-Allow-Headers
陈述415 (Unsupported Media Type)
所以暴力法也行不通
Finally
有没有人让它发挥作用并可以伸出援手,或者只是能够为我指明正确的方向?
EDIT
因此,为了完成 API 调用,我必须停止使用 JQuery 并切换到纯 JavascriptXMLHttpRequest
format.
尝试1
我设法得到了Microsoft.AspNetCore.Cors
按照 MindingData 的答案进行工作,除了在Configure
方法将app.UseCors
before app.UseMvc
.
此外,当与 Javascript API 解决方案混合时options.AllowAnyOrigin()
通配符支持也开始起作用。
尝试2
所以我已经成功地让尝试 2(暴力强制)工作......唯一的例外是通配符Access-Control-Allow-Origin
不起作用,因此我必须手动设置有权访问它的域。
这显然并不理想,因为我只是希望这个 WebAPI 向所有人广泛开放,但它至少在一个单独的网站上对我有用,这意味着它是一个开始
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"));