ASP.NET Core 6 MVC : SignInManager does not work with AddAuthentication for JwtBearer tokens

Viewed 50

I am doing an ASP.NET Core 6 MVC app and I implemented a SignInManager. I have my controller with Login method working like this

 public async Task<IActionResult> Login(LoginViewModel model, string? returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {
         
            var userExists = await _userManager.FindByEmailAsync(model.Email);
            if (userExists != null && await _userManager.CheckPasswordAsync(userExists, model.Password))
            {
                var result = await _signInManager.PasswordSignInAsync(userExists, model.Password, isPersistent: false, lockoutOnFailure: false);
            
                if (result.Succeeded)
                {
                    return directToAction("Admin", "Home");
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return View(model);
                }
            }
        }

        return View(model);
    }

Admin method in Home Controller has an [Authorize] attribute and it works fine.

[Authorize]
  public IActionResult Admin() => View();

The problem appeared when I added this snippet of code in program.cs

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("AuthConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();


var tokenValidationParameters = new TokenValidationParameters()
{
    ValidateIssuerSigningKey = true,
    IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(builder.Configuration["JWT:Secret"])),

    ValidateIssuer = true,
    ValidIssuer = builder.Configuration["JWT:Issuer"],

    ValidateAudience = true,
    ValidAudience = builder.Configuration["JWT:Audience"],

    ValidateLifetime = true,
    ClockSkew = TimeSpan.Zero
};
builder.Services.AddSingleton(tokenValidationParameters);


builder.Services.AddDefaultIdentity<ApplicationUser>(options =>
{
     options.SignIn.RequireConfirmedAccount = false;
    //  options.SignIn.RequireConfirmedEmail = true;
})
     .AddRoles<IdentityRole>()
      .AddEntityFrameworkStores<ApplicationDbContext>();


builder.Services.AddControllersWithViews();

//Add Authentication
builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})

//Add JWT Bearer
.AddJwtBearer(options =>
{
    options.SaveToken = true;
    options.RequireHttpsMetadata = false;
    options.TokenValidationParameters = tokenValidationParameters;
});


// Prevent Excessive authentication attempts
builder.Services.Configure<IdentityOptions>(options =>
{
    options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
    options.Lockout.MaxFailedAccessAttempts = 5;
    options.Lockout.AllowedForNewUsers = true;
});

// Apply Cross origin Resource Sharing. This is primarily for the WebAPI resources while consuming from a specific front end apps.
builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(builder =>
    {
        builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader();
    });

    // To Prevent Unknown user access
    options.AddPolicy("UnknownUserAccessCORS", builder =>
    {
        builder.WithOrigins("http://www.cobratest.com").AllowAnyHeader().AllowAnyMethod();
    });
});


var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
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.UseAuthentication();
app.UseAuthorization();

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

app.Run();

SignManager stopped working. Identity is null and when I when I call the method with [Authorize], I get an error

This page isn't working. If the problem continues, contact the site owner

This problem appears since I added

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})

If I remove rhis three lines, it works fine..

What it the problem with AddAuthentication?

Thanks

1 Answers

As I read here

It is not possible to use Jwt Auth and Identity Auth together

Related