Search code examples
asp.net-core-mvcasp.net-core-3.0

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


this is the image of the problem.

my login function in the 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");
        }

my login function in MVC with consume API _client.LoginAsync() is a static function to consume API for login

    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() is a function to consume api for login

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;
        }

my configuration for services

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();
    });
}

I complicated with this error I think this is everything if you want more to help me please tell me.


Solution

  • I found the solve

    if you face the same problem JWT does not support cookies with tokens together so you must remove

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

    from 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
            };
        });
    

    when you need to authorize any action by token you can use this attribute

    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    

    to any actions.

    when you need to authorize any action by cookie you need to add

    [Authorize]