ASP.NET Core MVC ChallengeResult, аргумент AuthenticationProperties не получен при методе перенаправленного действия

#asp.net-mvc #asp.net-core #.net-core #asp.net-authentication #.net-security

#asp.net-mvc #asp.net-core #.net-core #asp.net-аутентификация #.net-безопасность

Вопрос:

У меня очень простая настройка аутентификации:

 public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie();
    }
}
 

Теперь, когда MVC ChallengeResult возвращается (с AuthenticationProperties аргументом):

 public class HomeController : Controller
{ 
    public IActionResult Index()
    {
        if (!User.Identity.IsAuthenticated)
        {
            return Challenge(new AuthenticationProperties
            {
                IsPersistent = true
            });
        }
        else
        {
            return View();    
        }
    }
}
 

Запрос перенаправляется на /Account/Login и на следующий метод действия:

введите описание изображения здесь

Проблема: исходное назначение IsPersistent = true в методе Index() действия отсутствует, когда выполнение достигает метода Login() действия.

Приложение встроено в: .NET Core 3.1

Ответ №1:

Аргумент properties в действии login — это новый экземпляр. Он всегда будет нулевым. Потому что вы не присваиваете значение запросу. После возврата к Challenge , аутентификация инициирует перенаправление. Но перенаправление не будет содержать этот параметр.

Вы можете установить событие для сохранения значения контекста аутентификации cookie в сеансе.

 public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication("auth")
            .AddCookie("auth",config=>
            {
                config.Cookie.Name = "cookie.name";

                config.Events.OnRedirectToLogin = context =>
                {
                    context.HttpContext.Session.SetString("Properties",System.Text.Json.JsonSerializer.Serialize(context.Properties));
                    context.Response.Redirect("/home/login");
                    return Task.CompletedTask;
                };
            });
        services.AddSession();
        services.AddControllersWithViews();
    }
 

В действии login .

 public IActionResult login()
    {
        var get=HttpContext.Session.GetString("Properties");
        var deserializer = System.Text.Json.JsonSerializer.Deserialize<AuthenticationProperties>(get);
        return View();
    }
 

Затем свойства будут переданы в login.

введите описание изображения здесь

Комментарии:

1. Работает как шарм! Могу ли я предложить использовать context.RedirectUri вместо /home/login (чтобы у нас был returnUrl ). Также вы советуете не использовать параметры строки запроса для отправки выбранных свойств (вместо сеанса)? и пусть привязка модели для сопоставления с AuthenticationProperties

2. Да, я советую. Но если вы передаете много других атрибутов или конфиденциальной информации, это не рекомендуется.