我有一个 ASP.NET Core 3.1 API,但没有使用 CORS。据我了解,CORS 是浏览器的事情。由于来自另一个源的另一个站点的 ajax 调用被阻止到 API 端点(这很好),我仍然可以通过使用 Postman 或 HttpClient 和 GetAsync() 调用来到达相同的端点。
我的问题是是否也可以阻止对我的 API 的服务器到服务器调用(或 Postman 调用)?或者像 CORS 一样,只允许某些来源?
我的大多数端点都受到不记名 JWT token 的保护,但我有一个匿名端点,我希望只允许我控制(或可以配置)的源访问该匿名 API。
最佳答案
我在 stackoverflow 上看到这篇文章后解决了这个问题:
How do you create a custom AuthorizeAttribute in ASP.NET Core?
我只是创建了一个自定义授权属性[ApiAuthorize()]
,我这样调用:
[ApiController]
[ApiAuthorize(new string[] { "https://localhost:44351", "https://mysite.onthe.net" })]
public class MyInternalApiController : ControllerBase
{
...
}
它也可以在 Action 上实现,而不是在 Controller 上实现。实现是这样完成的:
public class ApiAuthorizeAttribute : TypeFilterAttribute
{
public ApiAuthorizeAttribute(string[] origins) : base(typeof(ApiAuthorizeFilter))
{
Arguments = new object[] { origins };
}
}
public class ApiAuthorizeFilter : IAuthorizationFilter
{
readonly string[] _origins;
public ApiAuthorizeFilter(string[] origins)
{
_origins = origins;
}
public void OnAuthorization(AuthorizationFilterContext context)
{
if (_origins == null)
return;
string referer = context.HttpContext.Request.Headers["Referer"].ToString();
if (string.IsNullOrWhiteSpace(referer) || !_origins.Any(origin => referer.StartsWith(origin, StringComparison.OrdinalIgnoreCase)))
context.Result = new ForbidResult();
}
}
需要考虑的事情:
- Referer 的实现和检查可以是精确匹配,而不是 StartsWith
- 可以使用正则表达式或任何好的替代方法来处理子域、通配符等
- 可以将引用者转换为 Uri 对象以获得更好的结果和变化
- jQuery ajax 调用按预期得到“403 - Forbidden”,但 Postman 得到“404 - Not Found”。对我来说这并不重要,但如果重要的话就值得研究。
但它满足了我的需要,所以我对此很满意。
关于asp.net-core - 阻止服务器到服务器或 Postman 对 ASP.NET Core 3.1 API 的调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65013583/