在 ASP.NET Core 6 中,有没有一种方法可以根据使用 URL 来限制某些操作方法?
In ASP.NET Core 6, is there a way to restrict certain action methods based on which URL is used?
在默认的 ASP.NET Core web API 应用程序中以 .NET 6 为目标,默认情况下它公开两个 URL 端点:一个位于 http://localhost:50xx,另一个在 https://localhost:70xx.
我想要做的是将第一个 (http) 用于 internal/trusted 客户端请求,将第二个 (https) 用于 internet/public 请求。所以很自然地,我想根据请求的来源来区别对待请求。
对于这两种类型的请求,我想使用 simple/default 路由匹配,但是 ,对于 HTTPS 请求,我想在选定的操作方法上启用白名单。结果是大多数请求根本无法通过 HTTPS 获得。
我觉得一定有一些简单的方法可以做到这一点,因为框架(和默认的应用程序模板)似乎已经通过提供 URLs...必须有一些方便的方法可以完成我所描述的,但我没有在文档中遇到它们。
谢谢
实施并应用全局自定义 ActionFilterAttribute,禁止 HTTPS 请求,但应用了自定义属性的 Controllers/Actions 除外。
1. 创建将应用于支持 HTTPS 请求的 contoller/methods 的自定义属性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AllowHttpsAttribute : Attribute { }
2. 创建自定义 ActionFilterAttribute
当控制器或操作没有 [ 时 short-circuits 通过 HTTPS 发出请求=16=] applied(short-circitung 是通过给 context.Result
赋值实现的):
public class HttpOnlyActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var isHttps = context.HttpContext.Request.Scheme == Uri.UriSchemeHttps;
if (isHttps && HttpsNotSupported(context))
{
context.Result = new BadRequestResult();
}
}
private bool HttpsNotSupported(ActionContext context)
{
return context.ActionDescriptor is ControllerActionDescriptor x &&
!x.ControllerTypeInfo.GetCustomAttributes<AllowHttpsAttribute>().Any() &&
!x.MethodInfo.GetCustomAttributes<AllowHttpsAttribute>().Any();
}
}
3. 全局应用 HttpOnlyActionFilter
(在 Program.cs):
builder.Services.AddControllers(x => x.Filters.Add<HttpOnlyActionFilter>());
用法:
应用于操作:
public class Controller : ControllerBase
{
// Allow requests over HTTPS
[HttpGet, AllowHttps]
public ActionResult Action1() => ...;
// Disallow requests over HTTPS
[HttpGet]
public ActionResult Action2() => ...;
}
应用于控制器:
[AllowHttps] // Allow requests over HTTPS
public class Controller : ControllerBase
{
...
}
在默认的 ASP.NET Core web API 应用程序中以 .NET 6 为目标,默认情况下它公开两个 URL 端点:一个位于 http://localhost:50xx,另一个在 https://localhost:70xx.
我想要做的是将第一个 (http) 用于 internal/trusted 客户端请求,将第二个 (https) 用于 internet/public 请求。所以很自然地,我想根据请求的来源来区别对待请求。
对于这两种类型的请求,我想使用 simple/default 路由匹配,但是 ,对于 HTTPS 请求,我想在选定的操作方法上启用白名单。结果是大多数请求根本无法通过 HTTPS 获得。
我觉得一定有一些简单的方法可以做到这一点,因为框架(和默认的应用程序模板)似乎已经通过提供 URLs...必须有一些方便的方法可以完成我所描述的,但我没有在文档中遇到它们。
谢谢
实施并应用全局自定义 ActionFilterAttribute,禁止 HTTPS 请求,但应用了自定义属性的 Controllers/Actions 除外。
1. 创建将应用于支持 HTTPS 请求的 contoller/methods 的自定义属性:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class AllowHttpsAttribute : Attribute { }
2. 创建自定义 ActionFilterAttribute
当控制器或操作没有 [ 时 short-circuits 通过 HTTPS 发出请求=16=] applied(short-circitung 是通过给 context.Result
赋值实现的):
public class HttpOnlyActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var isHttps = context.HttpContext.Request.Scheme == Uri.UriSchemeHttps;
if (isHttps && HttpsNotSupported(context))
{
context.Result = new BadRequestResult();
}
}
private bool HttpsNotSupported(ActionContext context)
{
return context.ActionDescriptor is ControllerActionDescriptor x &&
!x.ControllerTypeInfo.GetCustomAttributes<AllowHttpsAttribute>().Any() &&
!x.MethodInfo.GetCustomAttributes<AllowHttpsAttribute>().Any();
}
}
3. 全局应用 HttpOnlyActionFilter
(在 Program.cs):
builder.Services.AddControllers(x => x.Filters.Add<HttpOnlyActionFilter>());
用法:
应用于操作:
public class Controller : ControllerBase
{
// Allow requests over HTTPS
[HttpGet, AllowHttps]
public ActionResult Action1() => ...;
// Disallow requests over HTTPS
[HttpGet]
public ActionResult Action2() => ...;
}
应用于控制器:
[AllowHttps] // Allow requests over HTTPS
public class Controller : ControllerBase
{
...
}