.NET 6 Web应用设置UsePathBase后如何限制仅响应指定基础路径禁止根路径访问
解决方案
UsePathBase的作用是让应用支持指定路径前缀的请求,不会自动拦截不带前缀的请求,要实现仅响应/toolbox路径的请求,可以用以下几种方案:
方案1:添加自定义中间件拦截(全部署场景通用)
这是适配性最高的方案,不管是本地调试用Kestrel/IIS Express,还是部署到任意服务器都生效,直接在Program.cs中添加如下代码即可:
var builder = WebApplication.CreateBuilder(args); // 省略其余服务注册逻辑 var app = builder.Build(); const string BasePath = "/toolbox"; // 注册基础路径配置 app.UsePathBase(BasePath); // 新增路径校验中间件,注意要放在其余中间件之前注册 app.Use(async (context, next) => { // 校验请求路径是否以指定前缀开头 if (!context.Request.Path.StartsWithSegments(BasePath, StringComparison.OrdinalIgnoreCase)) { // 可选1:直接返回404 context.Response.StatusCode = StatusCodes.Status404NotFound; return; // 可选2:自动重定向到带前缀的对应路径,适合需要引导用户访问正确地址的场景 // context.Response.Redirect($"{BasePath}{context.Request.Path}{context.Request.QueryString}"); // return; } await next(); }); // 省略其余中间件注册,比如静态文件、路由、鉴权等 app.Run();
方案2:IIS/IIS Express部署场景用重写规则
如果你的应用是部署在IIS/IIS Express上,可以直接通过web.config配置重写规则,在反向代理层就拦截无效请求,性能更高:
在项目根目录的web.config(没有就新建)中添加如下配置:
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="ForceBasePath" stopProcessing="true"> <match url=".*" /> <conditions logicalGrouping="MatchAll"> <add input="{PATH_INFO}" pattern="^/toolbox(/.*)?$" negate="true" /> </conditions> <!-- 可选1:返回404 --> <action type="CustomResponse" statusCode="404" statusReason="Not Found" statusDescription="Resource not available" /> <!-- 可选2:重定向到正确路径 <action type="Redirect" url="toolbox/{R:0}" redirectType="Permanent" /> --> </rule> </rules> </rewrite> </system.webServer> </configuration>
方案3:全局路由前缀约束
如果你的应用所有接口/页面都需要强制带前缀,也可以在MVC路由配置层面统一加前缀,适合纯API或者单页应用场景:
首先定义路由前缀约定类:
public class RoutePrefixConvention : IControllerModelConvention { private readonly AttributeRouteModel _prefixModel; public RoutePrefixConvention(RouteAttribute prefix) { _prefixModel = new AttributeRouteModel(prefix); } public void Apply(ControllerModel controller) { foreach (var selector in controller.Selectors.Where(x => x.AttributeRouteModel != null)) { selector.AttributeRouteModel = AttributeRouteModel.CombineAttributeRouteModel(_prefixModel, selector.AttributeRouteModel); } } }
然后在Program.cs注册服务时引入:
const string BasePath = "/toolbox"; builder.Services.AddControllers(options => { options.Conventions.Insert(0, new RoutePrefixConvention(new RouteAttribute(BasePath))); });
内容的提问来源于stack exchange,提问作者SAL
相关产品推荐
相关产品推荐

