如何防止简单的 CORS GET 请求访问我的 ASP.Net Core API 服务器上的操作方法? [复制]
Posted
技术标签:
【中文标题】如何防止简单的 CORS GET 请求访问我的 ASP.Net Core API 服务器上的操作方法? [复制]【英文标题】:How to prevent simple CORS GET requests from accessing my Action Methods on my ASP.Net Core API Server? [duplicate] 【发布时间】:2021-03-02 15:08:27 【问题描述】:为了说明我的问题,当您使用 API 端点创建新项目时,我使用了默认的 ASP.Net Core 项目设置。这是我的控制器,带有Get
操作方法:
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
private static readonly string[] Summaries = new[]
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
;
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
_logger = logger;
[HttpGet]
public IEnumerable<WeatherForecast> Get()
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
)
.ToArray();
这是我在Startup
类中的Configure
方法(如您所见,我在开头添加了app.UseCors()
):
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseCors();
if (env.IsDevelopment())
app.UseDeveloperExceptionPage();
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
endpoints.MapControllers();
);
默认情况下,服务器在https://localhost:44391/
上运行。
现在我的期望是,使用像这样的默认设置,所有不是来自https://localhost:44391/
的 CORS 请求都应该被 CORS 策略阻止。为了验证我是否执行了以下步骤:
-
我启动了服务器并在我的
Get
方法中放置了一个断点
为了模拟跨域 (CORS) 请求,我访问了任意一个随机网站,例如https://***.com/ 打开 Chrome 开发工具并在控制台中运行以下请求我的 get 方法的 javascript:
fetch("https://localhost:44391/weatherforecast").then(r=>r.text()).then(console.log);
现在我预计服务器会发送一个 CORS 错误,而我的 Get
方法将永远不会被执行。
实际发生的情况是我的Get
方法中的断点被命中并执行了该方法。之后我才在浏览器控制台中看到了 CORS 错误。
我认为这种行为是错误的,因为如果请求来自另一个来源,我真的很想避免我的 Get
操作方法被完全执行。
所以基本上归结为两个问题:
-
为什么 ASP.Net Core CORS 策略以这种方式起作用?
是否有任何方法可以设置 CORS,使所有操作方法都不会执行,除非 CORS 策略允许?还是我需要为此编写一个自定义中间件?
【问题讨论】:
顺便说一句,CORS 是由浏览器执行的,而不是服务器。 【参考方案1】:"实际发生的是我的 Get 方法中的断点被命中 并执行了该方法。只有在那之后,我才看到 CORS 错误 我的浏览器控制台...我认为这种行为是错误的”
...不,这是预期的行为。 CORS 实际上是由浏览器执行的,基于服务器提供的标头,以及请求是否受 CORS 限制。
服务器无法确定请求是跨域 AJAX 请求还是其他类型的请求(因为 HTTP 请求中的数据不能可靠地提供该信息),因此直接拒绝不在其权力范围内请求。它所能做的就是设置 CORS 标头来告诉客户端如果请求实际上受到 CORS 限制该怎么办。
因此,如果您的请求到达服务器,将始终执行,只有当响应连同标头一起返回给浏览器时,浏览器才决定是否允许请求页面实际看到响应.
直接回答你的两个问题:
-
这就是 CORS 通常的工作方式,而不仅仅是 ASP.NET。请参阅上面的说明。
没有。再次,请参阅上面的解释。 (这里唯一的例外是需要飞行前 OPTIONS 请求的请求,其中必须向服务器发出单独的初始 HTTP OPTIONS 请求 - 在这种情况下,除非 OPTIONS 请求指示请求,否则不会命中 Action 方法是允许的。)
此优秀资源中提供了更多详细信息:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
【讨论】:
同样在这种情况下,请求被认为是“简单”请求,因此没有 OPTIONS / 飞行前请求来询问是否可以。 但是在服务器端阻止这些方法的执行不是更有意义吗?在我的脑海中,我认为这会使您的 API 对跨站点请求伪造和跨站点脚本攻击的抵抗力降低,不是吗? “在服务器端阻止这些方法的执行难道不是更有意义吗?”...当然,但正如我在答案中已经提到的,传入的 HTTP 请求的内容不会'没有给服务器足够的信息来可靠地做到这一点。它无法准确说明请求是如何生成的——它无法确定请求是否应该受到 CORS 的限制;只有浏览器才能知道。 "你可以只检查原始 HTTP 标头"...好吧,但问题是它很容易被欺骗,所以任何决心攻击你的服务器的人都会发现很容易绕过。这就是限制由浏览器强制执行的原因,使用 CORS 攻击向量的攻击者无法控制。而且,一个标准的非 AJAX 请求通常不会有该标头 - 因此,如果您基于该标头的存在进行阻止,那么如果它们不符合您的异常规范,您将冒着阻止所有非 AJAX 请求的风险. P.S. nccgroup.com/uk/about-us/newsroom-and-events/blogs/2017/… 很好地解释了为什么 CORS 和 CSRF 并不真正相互关联。 CORS 不会让您或多或少容易受到 CSRF 的攻击。如果您想要 CSRF 保护,无论您的 CORS 策略如何,都需要添加它(因为除此之外,CSRF 攻击可能发生在常规回发中,而不仅仅是 AJAX)。以上是关于如何防止简单的 CORS GET 请求访问我的 ASP.Net Core API 服务器上的操作方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章