Почему дубликат returnUrl перенаправляет логику в веб-приложениях asp.net с owin/identity?

Когда вы создаете новое веб-приложение (webforms или mvc) в visual studio, существует логика после аутентификации, которая проверяет параметр ReturnUrl в строке запроса и затем перенаправляет туда пользователя, если он существует: В weforms - Login.aspx.cs у вас есть это:

protected void LogIn(object sender, EventArgs e)
{
   ...
        switch (result)
        {
            case SignInStatus.Success:
                IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);
                break;
            ...
        }
    }
}

В MVC - AccountController.cs у вас есть это:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
   ...
    switch (result)
    {
        case SignInStatus.Success:
            return RedirectToLocal(returnUrl);
        ...
    }
}

Кроме того, конфигурация Owin настроена на использование аутентификации cookie, которая использует класс Microsoft.Owin.Security.Cookies.CookieAuthenticationHandler, который сам проверяет параметр ReturnUrl и применяет перенаправление, если он существует:

protected override async Task ApplyResponseGrantAsync()
{
    AuthenticationResponseGrant signin = Helper.LookupSignIn(Options.AuthenticationType);
    bool shouldSignin = signin != null;
    AuthenticationResponseRevoke signout = Helper.LookupSignOut(Options.AuthenticationType, Options.AuthenticationMode);
    bool shouldSignout = signout != null;

    if (shouldSignin || shouldSignout || _shouldRenew)
    {
        ...

        if ((shouldLoginRedirect || shouldLogoutRedirect) && Response.StatusCode == 200)
        {
            IReadableStringCollection query = Request.Query;
            string redirectUri = query.Get(Options.ReturnUrlParameter);
            if (!string.IsNullOrWhiteSpace(redirectUri)
                && IsHostRelative(redirectUri))
            {
                var redirectContext = new CookieApplyRedirectContext(Context, Options, redirectUri);
                Options.Provider.ApplyRedirect(redirectContext);
            }
        }
    }
}

Обе переадресации, как представляется, выполняются во время запроса на вход/аутентификацию. Один применяется к HttpContext.Response, а другой применяется к контексту перенаправления Owin. По моему опыту, похоже, что последний выигрыш переадресации вызовов, что является проблемой, если у вас есть специальная логика перенаправления, применяемая после входа в код вашего сайта, потому что она переопределяется встроенной переадресацией Owin.

Есть ли веская причина для этой повторяющейся логики? Это просто плохой дизайн? Итак, если я использую asp.net Owin CookieAuthentication, должен ли я иметь логику переадресации после входа в систему для контроллера учетной записи или кода aspx? И если это так, следует ли перенаправить на HttpContext.Response или через Owin?

Ответы

Ответ 1

Как вы сказали, эти три способа перенаправления всех принадлежат разным частям: WebForms, MVC, OWIN. Каждый из них может использоваться независимо от другого (OWIN в ситуации с самим хостингом), поэтому необходимо делать одно и то же в каждом из них.

Однако я не совсем уверен, зачем нужен последний шаблон MVC RedirectToLocal. Я бы пошел с обратной совместимостью - этот метод существовал целую вечность.

Также перенаправление OWIN не выигрывает в MVC - в одном из моих приложений я всегда перенаправляю пользователя в зависимости от их роли, даже если есть параметр с локальным URL-адресом, чтобы мои пользователи всегда попадали на указанную страницу в контроллере MVC.
Однако, взглянув на исходный код OWIN и логику перенаправления, кажется странным, что выигрывает MVC. Вероятно, нужно пройти весь путь вниз и посмотреть, что происходит в сценарии MVC.