在我的网站上,我有一些controller
仅限经过身份验证的用户使用。除此之外,还有一些控制器需要身份验证,还需要根据一年中的时间来限制ALSO。
为此,我创建了一个TimeRangeFilter
ActionFilter
/ ResourceFilter
。
是这样的:
public class TimeRangeFilter : Attribute, IActionFilter, IOrderedFilter
{
public string AllowedMonths { get; set; } // like |3|4|5|
public string RedirectUrl { get; set; }
...... // OnActionExecuting....
}
然后,在我的Controller
的{{1}}上,我这样实现:
class
但是,即使[TimeRangeFilter(AllowedMonths = "|3|4|", RedirectUrl = "/feature/welcome", Order = 1)]
[Authorize]
[IsNotNefarious]
public class HubController : BaseController
{...}
上有IOrderedFilter
interface
,filter
也会先执行,然后执行我的AuthorizationFilter
。
对于此欢迎页面,我不想要求用户登录才能看到它。但是我不想必须根据允许的月份来更改进入我的中心页面的URL。
如何在执行TimeRangeFilter
之前优先执行ActionFilter
/ ResourceFilter
并使其短路?
答案 0 :(得分:2)
@Alexander提供的解决方案在.NET Core 3.1中不再起作用;现在Authorize
中的AuthorizationMiddleware
属性正在评估中,需要经过很多步骤才能过滤条件。
最好的新方法是自己制作自定义中间件,将其插入UseRouting();
启动后,然后手动查询端点信息。示例:
public class TimeRangeAttribute : Attribute {
public string Info { get; set; }
}
public class TimeRangeMiddleware {
private readonly RequestDelegate _next;
public TimeRangeMiddleware(RequestDelegate next) => _next = next;
public async Task Invoke(HttpContext context) {
var endpoint = context.GetEndpoint();
if (endpoint?.Metadata.GetMetadata<TimeRangeAttribute>() != null) {
// check allowed or not
}
if(_next != null) await _next(context);
}
}
// In Startup
public void Configure(...) {
// ....
app.UseRouting();
app.UseMiddleware<TimeRangeMiddleware>();
app.UseAuthentication();
app.UseAuthorization();
// ...
}
答案 1 :(得分:1)
最简单的答案是“您不能使ActionFilter
在AuhtorizeFilter
之前执行”。但是您可以将TimeRangeFilter
设置为授权过滤器
public class TimeRangeFilterAttribute : Attribute, IAuthorizationFilter, IOrderedFilter
{
public string AllowedMonths { get; set; } // like |3|4|5|
public string RedirectUrl { get; set; }
public void OnAuthorization(AuthorizationFilterContext context)
{
if (not allowed) {
context.Result = new RedirectResult(RedirectUrl);
}
}
}
指定Order = 0
使其在其他Authorize
检查之前运行,或者尝试不对其实施IOrderedFilter
,它也会首先执行。 / p>