一种可能性是使用自定义authorization filter 创建一个带有失败状态代码的 HTTP 响应,例如 400 bad request 或 404 not found 如果请求具有不允许的主机。我们可以定义一个名为RestrictDomain 的授权过滤器,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
public class RestrictDomainAttribute : Attribute, IAuthorizationFilter
{
public IEnumerable<string> AllowedHosts { get; }
public RestrictDomainAttribute(params string[] allowedHosts) => AllowedHosts = allowedHosts;
public void OnAuthorization(AuthorizationFilterContext context)
{
// Get host from the request and check if it's in the enumeration of allowed hosts
string host = context.HttpContext.Request.Host.Host;
if (!AllowedHosts.Contains(host, StringComparer.OrdinalIgnoreCase))
{
// Request came from an authorized host, return bad request
context.Result = new BadRequestObjectResult("Host is not allowed");
}
}
}
如果要全局应用RestrictDomain 过滤器,则可以在Startup.cs 文件中添加过滤器,如下所示:
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
// Add the restrict domain filter globally
// You could read the allowed hosts from a config file, here we hard code them
options.Filters.Add(new RestrictDomainAttribute("localhost", "example.com"));
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints => endpoints.MapControllers());
}
}
使用此设置,如果我从构造函数中删除“localhost”并且只允许“example.com”,当我使用 Postman 时会收到 400 请求,因为主机将是 localhost。
另一个选项是直接在控制器或控制器操作中使用过滤器,因为我们将其配置为作为属性工作。但是,允许的主机必须是常数值,而不是可以在运行时计算的值。这是一个例子:
using Microsoft.AspNetCore.Mvc;
[Route("")]
[ApiController]
public class HomeController : ControllerBase
{
[HttpGet]
public ContentResult Index() => Content("Home");
[HttpGet("greeting")]
[RestrictDomain("localhost", "example.com")] // values must be constants
public ContentResult Greeting() => Content("Hello, World!");
}
如果您不想要常量值并且不想全局应用过滤器,那么您可以将IConfiguration 注入过滤器以读取可以访问资源的允许主机。