ASP.NET Core Web服务仅特定URL可访问及调用者URL获取方法问询
实现ASP.NET Core Web服务的特定URL访问限制
嘿,这个需求我刚好有实战经验,咱们一步步来搞定它~
首先你关心的如何获取调用者的URL地址,在ASP.NET Core里主要靠HttpContext.Request里的请求头来获取,常用的有两个:
Referer头:记录了用户是从哪个页面跳转过来的(注意拼写是Referer,不是Referrer,这是HTTP标准里的特殊拼写)Origin头:主要用于跨域请求(比如AJAX、Fetch调用),记录了发起请求的源域名
两者的区别是:Referer会包含完整的页面路径,而Origin只包含协议+域名+端口,对于API服务来说,Origin通常更可靠,因为很多API调用不会带Referer。
接下来咱们用中间件实现过滤逻辑,直接在Program.cs里写内联中间件就很方便,不用单独创建类:
步骤1:定义允许访问的白名单
先把你信任的URL/源列出来,比如:
var allowedTrustedSources = new[] { "https://your-trusted-site.com", "https://another-safe-domain.com" };
步骤2:添加自定义中间件
把这个中间件放在路由配置之后、端点配置之前,确保请求先经过过滤:
app.UseRouting(); // 自定义访问限制中间件 app.Use(async (context, next) => { // 获取Origin和Referer头 var origin = context.Request.Headers.Origin.FirstOrDefault(); var referer = context.Request.Headers.Referer.FirstOrDefault(); bool isAccessAllowed = false; // 优先检查Origin(适合API场景) if (!string.IsNullOrEmpty(origin)) { // 忽略大小写,检查是否在白名单内 isAccessAllowed = allowedTrustedSources.Any(source => origin.StartsWith(source, StringComparison.OrdinalIgnoreCase)); } // 再检查Referer(适合浏览器页面跳转场景) else if (!string.IsNullOrEmpty(referer)) { try { var refererUri = new Uri(referer); // 可以只检查域名部分,不用管具体路径 isAccessAllowed = allowedTrustedSources.Any(source => new Uri(source).Host.Equals(refererUri.Host, StringComparison.OrdinalIgnoreCase)); } catch (UriFormatException) { // 如果Referer格式无效,直接拒绝 isAccessAllowed = false; } } // 本地开发环境放行,方便调试 else if (context.Request.Host.Host == "localhost" && (context.Request.Host.Port == 5000 || context.Request.Host.Port == 7000)) { isAccessAllowed = true; } // 不允许访问则返回403 if (!isAccessAllowed) { context.Response.StatusCode = StatusCodes.Status403Forbidden; await context.Response.WriteAsync("Access Denied: Only trusted sources can access this service."); return; } // 允许访问,继续执行后续中间件 await next(); }); app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
重要注意事项
- HTTP头是可以被伪造的,所以这种方式适合内部服务调用或者信任的合作方调用,如果是面向公开的高安全场景,建议结合其他验证方式(比如API密钥)
- 有些客户端可能不会发送
Referer头,所以如果是API服务,最好要求调用方必须发送Origin头,或者在文档里说明依赖的请求头 - 白名单可以放在配置文件里(比如
appsettings.json),这样不用改代码就能更新
内容的提问来源于stack exchange,提问作者dace
相关产品推荐
相关产品推荐

