我們目前正在將 .NET Framework 4.8 MVC 應用程式遷移到 .NET (Core) 5,我遇到了挑戰。
在舊的框架應用程式中,我們實作AuthorizeAttribute了覆寫HandleUnauthorizedRequest將清除回應內容并“重新”執行另一個控制器(在 的幫助下IControllerFactory)。這實際上創建了一個登錄登錄頁面,其中 URL 保持不變(相同的請求)。對于具有此屬性的每個安全頁面,我們都會呈現一個不同的頁面(如您所愿的“推銷”)。
現在在 .NET Core 中,身份驗證的作業方式與在 .NET Framework 中不同。所以我相信前面描述的方法在這里行不通。我認為正確的方法是配置 cookie 身份驗證來處理這個問題。但是我們有兩個業務需求使得這有點挑戰性:
- 沒有重定向;相反,在第一個請求時顯示登錄頁面,所以基本上,URL 重寫/重新執行而不是重定向
- 每個需要身份驗證的頁面都應該呈現不同的登錄頁面
我的挑戰在于第一個要求。我需要找到一種在身份驗證時呈現不同控制器操作的方法。重新執行 URL 也可以,因為我們已經在自定義 UseStatusCodePages 處理程式中執行了此操作。看起來像我可以處理我的邏輯的AddAuthentication().AddCookie(o => o.Events.OnRedirectToLogin = context => { ... }地方,但我沒有嘗試過任何作業。一個原因可能是這對中間件來說太遠了?
所以問題是:如何對身份驗證挑戰進行重寫或重新執行而不是重定向?
uj5u.com熱心網友回復:
在同事的幫助下,查看了源代碼UseStatusCodePages和UseRewriter功能,我們想出了解決問題的方法。
我們最終OnRedirectToLogin在AddCookie. 當此事件被觸發時,我們會找到需要顯示的當前登錄頁面的 URI。但不是設定 `context.RedirectUri we instead add it to thecontext.HttpContext.Items dictionary. We then use custom middleware to look for that item and do the rewrite/re-execute there. Thereturn Task.CompletedTask;` 確保什么都沒有發生,沒有重定向。如果沒有中間件,我們會得到一個空白頁面。
services.AddAuthentication().AddCookie(o =>
{
o.Events.OnRedirectToLogin = context =>
{
var loginPageUri = GetLoginLandingPageUri(context);
context.HttpContext.Items[ReExecuteUriMiddleware.ReExecuteUriItemKey] = loginPageUri;
return Task.CompletedTask;
};
});
當中間件在 Items 字典中看到該專案時,我們重置端點資訊,因此當我們_next第二次呼叫時,中間件管道將很好地重新執行請求,但路徑不同。
public class ReExecuteUriMiddleware
{
public const string ReExecuteUriItemKey = "ReExecuteUri";
private readonly RequestDelegate _next;
public ReExecuteUriMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext httpContext)
{
await _next.Invoke(httpContext);
if (httpContext.Items[ReExecuteUriItemKey] is string reExecuteUri)
{
// An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
// the endpoint and route values to ensure things are re-calculated.
httpContext.SetEndpoint(null);
var routeValuesFeature = httpContext.Features.Get<IRouteValuesFeature>();
routeValuesFeature?.RouteValues?.Clear();
httpContext.Request.Path = reExecuteUri;
await _next.Invoke(httpContext);
}
}
}
當然,我們Startup在app.UseStatusCodePages().
app.UseMiddleware<ReExecuteUriMiddleware>();
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/456381.html
標籤:网 。网 asp.net-mvc asp.net 核心 验证
