ASP.NET Core 2.2. Можно ли использовать cookie-аутентификацию, если в браузере (IE11 и Edge) отключены cookie-файлы? - PullRequest
0 голосов
/ 27 марта 2019

Я обнаружил, что могу, поэтому я должен быть смущен насчет файлов cookie.

********** РАЗДЕЛ НАСТРОЙКИ **********

Я сделал следующее:

  1. Visual Studio 2017: Файл -> Новый проект -> Базовое веб-приложение ASP.NET -> Веб-приложение (модель-представление-контроллер). Все значения по умолчанию (таким образом, Нет аутентификации, и Настройка для HTTPS отмечена как истинная). Обозреватель решений будет выглядеть так:

enter image description here

  1. В Startup.cs я изменил ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        // THIS WAS COMMENTED OUT
        //services.Configure<CookiePolicyOptions>(options =>
        //{
        //    // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        //    options.CheckConsentNeeded = context => true;
        //    options.MinimumSameSitePolicy = SameSiteMode.None;
        //});
    
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    
        // THIS WAS ADDED
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = false;
                options.ExpireTimeSpan = TimeSpan.FromSeconds(20);
            });
    }
    
  2. В Startup.cs я изменил Configure:

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
            app.UseHsts();
        }
    
        app.UseHttpsRedirection();
        app.UseStaticFiles();
        // THIS WAS COMMENTED OUT
        //app.UseCookiePolicy();
        // THIS WAS ADDED
        app.UseAuthentication();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    
  3. В классе для HomeController.cs, который создан для вас, я добавил тег [Authorize]:

        [Authorize]
        public class HomeController : Controller
        {
    
  4. Я добавил новый файл класса в папку Models с именем AccountModel.cs, вот как это выглядит:

    namespace WebApplication1.Models
    {
        public class LoginViewModel
        {
            [Required]
            [Display(Name = "Email")]
            [EmailAddress]
            public string Email { get; set; }
    
            [Required]
            [DataType(DataType.Password)]
            [Display(Name = "Password")]
            public string Password { get; set; }
    
            [Display(Name = "Remember me?")]
            public bool RememberMe { get; set; }
        }
    }
    
  5. Я создал новую папку с именем Data и добавил новый файл класса с именем ApplicationUser.cs:

    namespace WebApplication1.Data
    {
        public class ApplicationUser
        {
            public string Email { get; set; }
            public string FullName { get; set; }
        }
    }
    
  6. Я добавил новый файл класса в папку Controllers под названием AccountControleler.cs, вот как это выглядит:

    namespace WebApplication1.Controllers
    {
        public class AccountController : Controller
        {
            public IActionResult Login()
            {
                return View();
            }
    
            [HttpPost]
            [ValidateAntiForgeryToken]
            public async Task<IActionResult> Login(LoginViewModel model, string returnUrl)
            {
                if (!ModelState.IsValid)
                {
                    return View(model);
                }
    
                ApplicationUser appUser = await AuthenticateUser(model.Email, model.Password);
    
                if (appUser == null)
                {
                    ModelState.AddModelError("", "Invalid login attempt.");
                    return View(model);
                }
    
                List<Claim> claims = new List<Claim>
                {
                    new Claim(ClaimTypes.Name, appUser.FullName),
                    new Claim("FullName", appUser.FullName),
                    new Claim(ClaimTypes.Email, appUser.Email),
                    new Claim(ClaimTypes.Role, "Administrator")
                };
    
                ClaimsIdentity claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
    
                AuthenticationProperties authProperties = new AuthenticationProperties();
    
                await HttpContext.SignInAsync(
                    CookieAuthenticationDefaults.AuthenticationScheme,
                    new ClaimsPrincipal(claimsIdentity),
                    authProperties);
    
                return RedirectToLocal(returnUrl);
            }
    
            private async Task<ApplicationUser> AuthenticateUser(string email, string password)
            {
                await Task.Delay(500);
    
                if (email == "so@test.com")
                {
                    return new ApplicationUser()
                    {
                        Email = "so@test.com",
                        FullName = "Stack Overflow"
                    };
                }
                else
                {
                    return null;
                }
            }
    
            private ActionResult RedirectToLocal(string returnUrl)
            {
                if (Url.IsLocalUrl(returnUrl))
                {
                    return Redirect(returnUrl);
                }
                return RedirectToAction("Index", "Home");
            }
        }
    }
    
  7. Я создал новую папку в папке Views с именем Account и добавил новый класс с именем Login.cshtml:

    @model WebApplication1.Models.LoginViewModel
    @{
        ViewData["Title"] = "Login";
    }
    
    <h2 class="text-primary">@ViewBag.Title</h2>
    <div class="row">
        <div class="col-md-8">
            <section id="loginForm">
                @*https://dustinewers.com/how-to-build-html-helpers-like-html-beginform-in-asp-net-mvc/*@
                @*https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.rendering.ihtmlhelper.beginform?view=aspnetcore-2.2*@
                @*@Html.BeginForm("Login", "Account",TModel-routeValues,FormMethod.Post, bool?-AntiforgeryExtensions, TModel-htmlAttributes)*@
                @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, null, new { @class = "form-horizontal", role = "form" }))
                {
                    @Html.AntiForgeryToken()
                    <h4 class="text-primary">Use a local account to log in.</h4>
                    <hr />
                    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
                    <div class="form-group">
                        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" })
                        <div class="col-md-10">
                            @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
                            @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" })
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <div class="checkbox">
                                @Html.CheckBoxFor(m => m.RememberMe)
                                @Html.LabelFor(m => m.RememberMe)
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <div class="col-md-offset-2 col-md-10">
                            <input type="submit" value="Log in" class="btn btn-default btn-primary" />
                        </div>
                    </div>
                    <p>
                        @Html.ActionLink("Register as a new user", "Register")
                    </p>
                    @* Enable this once you have account confirmation enabled for password reset functionality
                        <p>
                            @Html.ActionLink("Forgot your password?", "ForgotPassword")
                        </p>*@
                }
            </section>
        </div>
    </div>
    
  8. Это мои настройки браузера (IE11) для файлов cookie:

enter image description here

********** ЗДЕСЬ, ЧТО ЭТО ВЫглядит, КАК когда я запускаю приложение **********

Исходя из того, что я настроил, при запуске приложения оно переместится на страницу входа в систему, и я не смогу перейти ни в один из домашних или конфиденциальных видов, пока не войду в систему. Это работает. Это не проблема.

Я хотел посмотреть, что произойдет, если я отключу куки в браузере. Я знаю, что правильно отключил файлы cookie, потому что, если я попытаюсь войти в Facebook, я получу сообщение «Требуются файлы cookie». Тем не менее, я могу запустить мое маленькое тестовое приложение для моего сердца, и оно войдет в систему, истечет через 20 секунд (что приведет к повторному входу в систему, как только я нажму на ссылку) и т. Д. Без потери функциональности, это работает.

  1. При первом запуске приложения с отключенными файлами cookie:

enter image description here

  1. Затем я вхожу в систему, используя моего пользователя so@test.com (введите любой пароль):

enter image description here

... И я могу перейти к любому желаемому виду.

Так чего мне здесь не хватает? Означает ли авторизация файлов cookie нечто иное, чем файлы cookie, связанные с вашим браузером? Или это какой-то тип файлов cookie сервера (против файла cookie клиента или чего-то еще)? Или ASP.NET Core каким-то образом решает эту проблему?

********** НОВАЯ ИНФОРМАЦИЯ **********

Похоже, я должен был попробовать другой браузер, кроме IE. Firefox и Chrome сделали как положено, тогда как IE и Edge игнорируют тот факт, что у меня заблокированы куки. Кто-нибудь знает почему? Это какая-то особая магия для браузеров Microsoft, которую другие браузеры не имеют / получают?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...