微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Cookie 身份验证失败 ASP.NET Core 3.1

如何解决Cookie 身份验证失败 ASP.NET Core 3.1

我没有将现有的 ASP.NET Core 2.1 项目迁移到 3.1,而是创建了一个新项目。在新项目中,SignIn(...) 控制器方法执行没有错误,但随后无法重定向到指定的操作。相反,它重定向AccessDeniedpath

我的环境是使用 Chrome 的 Win10 VS 2019 IIS Express。

谁能告诉我是什么原因造成的?我在 3.1 中有什么遗漏或做错了吗?

PROGRAM.CS

public static void Main(string[] args)
{
    CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
            //webBuilder.UseIISIntegration();
            //webBuilder.UseKestrel();
            //webBuilder.CaptureStartupErrors(true);
            //webBuilder.UseEnvironment(Environments.Development);
        });

STARTUP.CS

    public void ConfigureServices(IServiceCollection services)
    {
        try
        {
            services.AddRazorPages()        
                .AddRazorRuntimeCompilation();

            services.AddControllersWithViews();

            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme,options =>
                {
                    options.ExpireTimeSpan = new TimeSpan(30,0);
                    options.LoginPath = new PathString("/Home/Index/");
                    options.AccessDeniedpath = new PathString("/Home/Index/");
                    options.logoutPath = new PathString("/Home/Index/");
                    options.Validate();
                });

            services.Configure<Microsoft.AspNetCore.Identity.IdentityOptions>(options =>
            {
                options.Password.requiredigit = true;
                options.Password.RequireLowercase = true;
                options.Password.RequireNonAlphanumeric = true;
                options.Password.RequireUppercase = true;
                options.Password.requiredLength = 8;
                options.Password.requiredUniqueChars = 1;
                options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
                options.Lockout.MaxFailedAccessAttempts = 5;
                options.Lockout.AllowedForNewUsers = true;
                options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMnopQRSTUVWXYZ0123456789-._@+";
            });

            services.AddDetectionCore()
                .AddDevice();

            services.AddMvc();
            services.AddAntiforgery();
            services.Configure<Mvcoptions>(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
            });
        }
        catch (Exception ex)
        {
            gFunc.ProcessError(ex);
        }
    }

    public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
    {
        try
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }
            app.UseStaticFiles();
            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseAuthentication();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllerRoute(
                    name: "default",pattern: "{controller=Home}/{action=Index}/{id?}");
            });
        }
        catch (Exception ex)
        {
            gFunc.ProcessError(ex);
        }
    }

CONTROLLER.CS

    [HttpPost()]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> SignIn(SignIn sin)
    {
        bool is_err = false;
        try
        {
            // check data
            if (string.IsNullOrEmpty(sin.EmailAddress))
            {
                is_err = true;
                ModelState.AddModelError("Samadhi","Missing email address.");
            }
            if (string.IsNullOrEmpty(sin.Password))
            {
                is_err = true;
                ModelState.AddModelError("Samadhi","Missing password.");
            }

            // check authorisation
            if (ModelState.IsValid && !is_err)
            {
                sin = await RepoSamadhi.ShopSignIn(sin);
                if (sin.ShopID == 0 || sin.IsValidationFail || string.IsNullOrEmpty(sin.ShopToken))
                {
                    is_err = true;
                    ModelState.AddModelError("Samadhi","Account not found. Check your credentials.");
                }
            }

            // check model state
            if (!ModelState.IsValid || is_err)
            {
                sin.IsSignInFailed = true;
                return View("SignIn",sin);
            }

            // create claims
            var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Sid,sin.ShopToken),new Claim(ClaimTypes.NameIdentifier,sin.ShopID.ToString()),new Claim(ClaimTypes.Email,sin.EmailAddress.ToLower()),new Claim(ClaimTypes.Role,"SamadhiShop")
        };

            // create identity
            var identity = new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme); 

            // create principal
            ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(claims,CookieAuthenticationDefaults.AuthenticationScheme));

            var authProperties = new AuthenticationProperties
            {
                IsPersistent = true // sin.RememberMe
            };

            // sign-in
            await HttpContext.SignInAsync(scheme: CookieAuthenticationDefaults.AuthenticationScheme,principal: principal,properties: authProperties);
        }
        catch (Exception ex)
        {
            gFunc.ProcessError(ex);
        }
        return RedirectToAction("Console",new { date = DateTime.Today.ToString("d MMM yyyy"),timer = false });
    }

    [HttpGet]
    [Authorize]
    public async Task<ActionResult> Console(string date,bool timer)
    {
        int shop_id = int.Parse(User.FindFirst(ClaimTypes.NameIdentifier).Value);
        string token = User.FindFirst(ClaimTypes.Sid).Value;

        DateTime dt = DateTime.Parse(date);
        Shop ss = await RepoSamadhi.GetShop(shop_id,token,dt);
        ss.IsTimerOn = timer;
        return View((_device.Type == DeviceType.Mobile) ? "ConsoleM" : "ConsoleM",ss);
    }

解决方法

你中间件的顺序不对,正确的应该是

app.UseAuthentication(); 
app.UseAuthorization(); 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。