![](/img/trans.png)
[英]ASP.NET MVC Global or BaseController ActionFilter to Execute Before OnAuthorization
[英]ASP.NET Core MVC ActionFilter execute before AuthorizationFilter
在我的站點上,我有一些controller
僅限於經過身份驗證的用戶。 除此之外,還有一些控制器需要身份驗證,還需要根據一年中的時間進行限制。
為了解決這個問題,我創建了一個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
的class
,我是這樣實現的:
[TimeRangeFilter(AllowedMonths = "|3|4|", RedirectUrl = "/feature/welcome", Order = 1)]
[Authorize]
[IsNotNefarious]
public class HubController : BaseController
{...}
但是,即使filter
上有IOrderedFilter
interface
, AuthorizationFilter
IOrderedFilter
首先執行,然后是我的TimeRangeFilter
。
對於這個歡迎頁面,我不想要求用戶登錄才能看到它。 但我不想根據允許的月份更改訪問我的中心頁面的 URL。
在AuthorizationFilter
執行之前,如何優先執行ActionFilter
/ ResourceFilter
使其短路?
簡短的回答是“你不能讓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
實現IOrderedFilter
並且它也將首先執行。
@Alexander 的解決方案不再適用於 .NET Core 3.1; 現在Authorize
屬性在被評估AuthorizationMiddleware
,過濾器之前許多步驟被擊中。
最好的新方法是自己做一個自定義的中間件,在UseRouting();
之后插入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();
// ...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.