簡體   English   中英

ASP.NET Core MVC ActionFilter 在 AuthorizationFilter 之前執行

[英]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....
}

然后,在我的Controllerclass ,我是這樣實現的:

[TimeRangeFilter(AllowedMonths = "|3|4|", RedirectUrl = "/feature/welcome", Order = 1)]
[Authorize]
[IsNotNefarious]
public class HubController : BaseController
{...}

但是,即使filter上有IOrderedFilter interfaceAuthorizationFilter IOrderedFilter首先執行,然后是我的TimeRangeFilter

對於這個歡迎頁面,我不想要求用戶登錄才能看到它。 但我不想根據允許的月份更改訪問我的中心頁面的 URL。

AuthorizationFilter執行之前,如何優先執行ActionFilter / ResourceFilter使其短路?

簡短的回答是“你不能讓ActionFilterAuhtorizeFilter之前執行”。 但是你可以把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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM