User.Identity.IsAuthenticated = false 登录成功后 mvc core 3.0 with web api

User.Identity.IsAuthenticated = false after login successfully mvc core 3.0 with web api

这是图像明显的问题。

我的登录功能在api

        public async Task<object> Login([FromBody] LoginDto model)
        {
            var user = _context.Users.FirstOrDefault(x => x.Email == model.Email || x.UserName == model.Email);
            var result = await _signInManager.PasswordSignInAsync(user.UserName, model.Password, model.RememberMe, false);
            var IsAuthenticate = User.Identity.IsAuthenticated;
            await _signInManager.SignInAsync(user, model.RememberMe);
            if (result.Succeeded)
            {
                var appUser = _userManager.Users.SingleOrDefault(r => r.Email == model.Email);
                return await GenerateJwtToken(model.Email, appUser);
            }

            return BadRequest("INVALID_LOGIN_ATTEMPT");
        }

我在 mvc 中使用 consume 登录功能 api _client.LoginAsync() 是使用 api 进行登录的静态函数

    public async Task<IActionResult> Login(LoginDto model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
            try
            {
                await _client.LoginAsync<LoginDto>(new Uri(_appSettings.WebApiBaseUrl + "Account/Login"), model);
                ApplicationManager.SetMessageToUser("تم تسجيل الدخول بمجاح");
                await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, false);
                return Redirect("/" + returnUrl);
            }
            catch
            {

            }
        }
        ApplicationManager.SetMessageToUser("تأكد من اسم المستخدم وكلمة المرور");

        // If we got this far, something failed, redisplay form
        return View(model);
    }

_client.LoginAsync() 是使用 api 登录的函数

public async Task<string> LoginAsync<T>(Uri requestUrl, T content)
        {
            addHeaders();
            var response = await _httpClient.PostAsync(requestUrl.ToString(), CreateHttpContent<T>(content));
            string st = response.Content.ReadAsStringAsync().Result;

            response.EnsureSuccessStatusCode();
            var data = await response.Content.ReadAsStringAsync();
            return (string)data;
        }

我的服务配置

public void ConfigureServices(IServiceCollection services)
{
    services.AddSession(options => {
        options.IdleTimeout = TimeSpan.FromMinutes(60);
    });
    services.Configure<AppSettings>(Configuration.GetSection("AppSettings")); 
    services.AddDbContext<ApplicationDbContext>(opt =>
       opt.UseSqlServer("Data Source=.;Initial Catalog=ECommerceWebDb;Integrated Security=True"));

    services.AddIdentity<IdentityUser, IdentityRole>(options =>
    {
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequiredLength = 8;
        options.User.RequireUniqueEmail = true;
    })
       .AddEntityFrameworkStores<ApplicationDbContext>()
       .AddDefaultTokenProviders();

    services.AddControllers();
    services.AddCors();
    services.AddMvc();
    services.AddControllersWithViews();
    services.AddRazorPages();
    var appSettingsSection = Configuration.GetSection("AppSettings");
    services.Configure<AppSettings>(appSettingsSection);

    // configure jwt authentication
    var appSettings = appSettingsSection.Get<AppSettings>();
    var key = Encoding.ASCII.GetBytes(appSettings.Secret);
    services.AddAuthentication(x =>
    {
        x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

    })
    .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;

        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
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.UseCors();


    app.UseAuthentication();

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

        endpoints.MapAreaControllerRoute(
         name: "areas", "areas",
         pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}");
        endpoints.MapRazorPages();
    });
}

这个错误让我很复杂 我认为这一切如果你想要更多帮助我请告诉我。

SignIn 为以后的请求保留给定的信息,它不会在当前 one.So 上设置 HttpContext.User User.Identity.IsAuthenticated 将在后续请求中为真

参考

https://github.com/aspnet/Security/issues/1318

https://docs.microsoft.com/en-us/archive/msdn-magazine/2017/september/cutting-edge-cookies-claims-and-authentication-in-asp-net-core#foundation-of-aspnet-authentication

n ASP.NET, user authentication involves the use of cookies. Any users that attempt to visit a private page are redirected to a login page if they don't carry a valid authentication cookie. The login page, after having verified provided creden-tials, emits the cookie, which then travels with any subsequent requests from that user through the same browser until it expires. This is the same basic workflow you might know from past versions of ASP.NET. In ASP.NET Core, it only looks different because of the different middleware and the different configuration of the runtime environment.

我找到了答案

如果您遇到同样的问题,JWT 不支持将 cookie 与令牌一起使用,因此您必须删除

x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

来自 services.AddAuthentication

    services.AddAuthentication(x =>
    {

    })
    .AddJwtBearer(x =>
    {
        x.RequireHttpsMetadata = false;
        x.SaveToken = true;

        x.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(key),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

当您需要通过令牌授权任何操作时,您可以使用此属性

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

任何动作。

当您需要通过 cookie 授权任何操作时,您需要添加

[Authorize]