Asp.Net Core 3.1 Cookie身份验证循环到登录页面

时间:2020-02-18 21:43:48

标签: c# asp.net authentication cookies core

我的配置是:

HomeController.cs

public class HomeController : Controller
{
    [Authorize]
    public IActionResult Index()
    {
        return this.View("Index");
    }
}

Startup.cs

public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddCookie(options =>
            {
                options.LoginPath = "/auth/login/";
                options.ExpireTimeSpan = TimeSpan.FromDays(7);
                options.Events.OnValidatePrincipal = ValidateAsync;
            });

        services.AddControllersWithViews();

        services.AddAntiforgery();

        services.AddDbContext<ApplicationDbContext>((serviceProvider, options) =>
        {
            options.UseSqlServer(this.Configuration.GetConnectionString("DefaultConnection"));
            options.EnableSensitiveDataLogging();
        });
    }

public void Configure(IApplicationBuilder app, IWebHostEnvironment 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();

        app.UseRouting();

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

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }

public static async Task ValidateAsync(CookieValidatePrincipalContext context)
    {
        context = context ?? throw new ArgumentNullException(nameof(context));

        String userId = context.Principal.Claims.FirstOrDefault(claim => claim.Type == ClaimTypes.NameIdentifier)?.Value;

        if(userId == null)
        {
            context.RejectPrincipal();
            await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return;
        }

        ApplicationDbContext dbContext = context.HttpContext.RequestServices.GetRequiredService<ApplicationDbContext>();
        User user = await dbContext.Users.FindAsync(Guid.Parse(userId));

        if(user == null)
        {
            context.RejectPrincipal();
            await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return;
        }

        if(!user.StaySignedIn && 
            user.LastLogin != null && 
            (user.LastLogin.Subtract(TimeSpan.FromDays(1)) > DateTimeOffset.Now))
        {
            context.RejectPrincipal();
            await context.HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
            return;
        }
    }

AuthController.cs

[Route("/login")]
    [Route("/auth/login")]
    public async Task<IActionResult> Login([FromForm]LoginModel loginModel)
    {
        Claim nameIdentifier = new Claim(ClaimTypes.NameIdentifier, user.Id.ToString());

        ClaimsIdentity userIdentity = new ClaimsIdentity(new List<Claim> { nameIdentifier }, CookieAuthenticationDefaults.AuthenticationScheme);
        ClaimsPrincipal claimsPrincipal = new ClaimsPrincipal(userIdentity);

        await this.HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal);
        return this.RedirectToAction("Index", "Home");
    }

问题: 当我成功登录到http上下文并重定向到家庭控制器时,由于我不知道,所以HomeController的Authorize Attribute将我重定向到登录路径。 (无限循环)

validate async方法不会注销我或拒绝cookie(我已对其进行检查。)

但是问题出在哪里? 我在asp.net core 2.1项目中具有相同的身份验证过程,并且在这里可以正常工作。

我使用自定义的authorize属性对其进行测试,以检查上下文。在这种情况下,我有一个委托人并已通过身份验证。

但是为什么要重定向我的标准授权属性?

关于, Duesmannr

3 个答案:

答案 0 :(得分:2)

我找到了解决问题的方法。

顺序

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

必须更改,然后才能起作用。

答案 1 :(得分:0)

已关闭的问题使用身份时不允许使用cookie。 它会覆盖某些信息。 Git Discussion

答案 2 :(得分:0)

Cookie选项告诉身份验证中间件cookie在浏览器中的工作方式。在Startup类中,将此代码添加到您的ConfigureServices方法中

     services.AddAuthentication(options =>
        {
            options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        }).AddCookie(options => { options.LoginPath = "/Login"; });
相关问题