Bearer error=”invalid_token”,error_description=”The signature key was not found”

I am new to asp.net identity and jwt token authentification and having trouble authorizing API endpoints, or more exactly making calls to enpoints that require authorization. I created an Asp.net Core API with a custom database to which i added Identity on the user table. Everything worked fine untill i added the JWT Authentication. Then all the enpoints that require authorization fail : 401 UNAUTHORIZED Bearer error=”invalid_token”,error_description=”The signature key was not found”.
This is what i have in Program.Cs :

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        var configuration = builder.Configuration;
        builder.Logging.AddConsole();

        var host = builder.Configuration["DBHOST"];
        var port = builder.Configuration["DBPORT"];
        var user = builder.Configuration["DBUSER"];
        var password = builder.Configuration["DBPASSWORD"];
        var database = builder.Configuration["DBNAME"];

        builder.Services.AddCors(policy =>
        {
            policy.AddPolicy("CorsAllAccessPolicy", opt =>
            opt.AllowAnyOrigin()
            .AllowAnyHeader()
            .AllowAnyMethod());
        });

        var connectionString = $"Server={host},{port};Database={database};User Id={user};Password={password};TrustServerCertificate=True;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=False;";

        //var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
        builder.Services.AddDbContext<GrdbContext>(options => options.UseSqlServer(connectionString));

        ConfigureAutoMapper(builder.Services);

        builder.Services.AddScoped<IDbService, DbService>();
        builder.Services.AddSingleton(x => new BlobServiceClient("DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://storage:10000/devstoreaccount1;QueueEndpoint=http://storage:10001/devstoreaccount1;"));

        builder.Services.AddIdentity<GrdbUser, IdentityRole<int>>(options =>
        {
            options.Password.RequireDigit = true;
            options.Password.RequireLowercase = true;
            options.Password.RequireUppercase = true;
            options.Password.RequireNonAlphanumeric = false;
        })
            .AddEntityFrameworkStores<GrdbContext>()
            .AddDefaultTokenProviders();


        builder.Services.AddAuthentication(options =>
        {
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.SaveToken = true;
            options.RequireHttpsMetadata = false;
            options.TokenValidationParameters = new TokenValidationParameters()
            {
                RequireExpirationTime = true,
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidAudience = configuration["JWT:VAlidAudience"],
                ValidIssuer = configuration["JWT:ValidIssuer"],
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["JWT:SecretKey"]))
            };
        });


        builder.Services.AddControllers();
        // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
        builder.Services.AddEndpointsApiExplorer();
        //builder.Services.AddSwaggerGen();
        builder.Services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo { Title = "GRDB Database", Version = "v1" });

            // Define JWT bearer token authentication
            var securityScheme = new OpenApiSecurityScheme
            {
                Name = "Authorization",
                Description = "JWT Authorization header using the Bearer scheme",
                Type = SecuritySchemeType.Http,
                Scheme = "bearer",
                BearerFormat = "JWT"
            };
            c.AddSecurityDefinition("Bearer", securityScheme);

            // Make sure Swagger UI requires a Bearer token
            c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
    {
        new OpenApiSecurityScheme
        {
            Reference = new OpenApiReference
            {
                Type = ReferenceType.SecurityScheme,
                Id = "Bearer"
            }
        },
        Array.Empty<string>()
    }
});
        });


        var app = builder.Build();

        using (var scope = app.Services.CreateScope())
        {
            var dbContext = scope.ServiceProvider.GetRequiredService<GrdbContext>();
            InitializeDatabase(dbContext);
        }

        // Configure the HTTP request pipeline.
        //if (app.Environment.IsDevelopment())
        //{
        //    app.UseSwagger();
        //    app.UseSwaggerUI();
        //}
        app.UseSwagger();
        app.UseSwaggerUI();
        app.UseCors("CorsAllAccessPolicy");
        app.UseAuthentication();
        app.UseAuthorization();


        app.MapControllers();

        app.Run();
    }


    static void ConfigureAutoMapper(IServiceCollection services)
    {
        var config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<BookAuthor, AuthorDTO>().ReverseMap();
            cfg.CreateMap<BookAuthor, AuthorCreateDTO>().ReverseMap();
            cfg.CreateMap<BookGenre, GenreDTO>().ReverseMap();
            cfg.CreateMap<BookGenre, GenreCreateDTO>().ReverseMap();
            cfg.CreateMap<BookAuthorConnection, AuthorDTO>().ReverseMap();
            cfg.CreateMap<BookGenreConnection, GenreDTO>().ReverseMap();
            cfg.CreateMap<BookReview, BookReviewDTO>().ReverseMap();
            cfg.CreateMap<BookReview, BookReviewCreateDTO>().ReverseMap();
            cfg.CreateMap<BookReview, BookReviewUpdateDTO>().ReverseMap();
            cfg.CreateMap<GrdbUser, GrdbUserDTO>().ReverseMap();
            cfg.CreateMap<GrdbUser, GrdbUserCreateDTO>().ReverseMap();
            cfg.CreateMap<GrdbUser, GrdbUserUpdateDTO>().ReverseMap();
            cfg.CreateMap<Book, BookDTO>().ReverseMap();
            cfg.CreateMap<Book, BookCreateDTO>().ReverseMap();
            cfg.CreateMap<Book, BookUpdateDTO>().ReverseMap();
        });
        var mapper = config.CreateMapper();
        services.AddSingleton(mapper);
    }

    public static void InitializeDatabase(GrdbContext dbContext)
    {
        // Apply any pending migrations
        dbContext.Database.Migrate();

        // Add your custom initialization logic here
        // For example, you can seed initial data or create additional tables

        // Save the changes to the database
        dbContext.SaveChanges();
    }

And this is what i have in appSettings :

"JWT": {
  "SecretKey": "secretpa$$word",
  "ValidIssuer": "grdb.adminui.server",
  "ValidAudience": "grdb.clients",
  "ExpirationInMinutes": 1440
}

Then i created an AuthenticationController that looks like this :

   [Route("api/[controller]")]
   [ApiController]
   public class AuthenticateController : ControllerBase
   {
       private readonly UserManager<GrdbUser> _userManager;
       private readonly RoleManager<IdentityRole<int>> _roleManager;
       private readonly IConfiguration _configuration;


       public AuthenticateController(
           UserManager<GrdbUser> userManager,
           RoleManager<IdentityRole<int>> roleManager,
           IConfiguration configuration)
       {
           _userManager = userManager;
           _roleManager = roleManager;
           _configuration = configuration;

       }

       [HttpPost]
       [Route("login")]
       public async Task<IActionResult> Login([FromBody] LoginModel model)
       {
           var user = await _userManager.FindByNameAsync(model.Username);
           if (user != null && await _userManager.CheckPasswordAsync(user, model.Password))
           {
               var userRoles = await _userManager.GetRolesAsync(user);

               var authClaims = new List<Claim>
               {
                   new Claim(ClaimTypes.Name, user.UserName),
                   new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
               };

               foreach (var userRole in userRoles)
               {
                   authClaims.Add(new Claim(ClaimTypes.Role, userRole));
               }

               if (authClaims.Count > 0)
               {
                   var token = GetToken(authClaims);

                   return Ok(new AuthenticationResult
                   {
                       Token = new JwtSecurityTokenHandler().WriteToken(token),
                       Expiration = token.ValidTo,
                       User = new LoggedUser
                       {
                           Id = user.Id,
                           Username = user.UserName,
                           Email = user.Email,
                           Roles = (List<string>)userRoles
                       }
                   });
               }
           }
           return Unauthorized();
       }

       [HttpPost]
       [Route("register")]
       public async Task<IActionResult> Register([FromBody] RegisterModel model)
       {
           var userExists = await _userManager.FindByNameAsync(model.Username);
           if (userExists != null)
               return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "Error", Message = "User already exists!" });

           GrdbUser user = new()
           {
               Email = model.Email,
               SecurityStamp = Guid.NewGuid().ToString(),
               UserName = model.Username,
           };
           var result = await _userManager.CreateAsync(user, model.Password);
           if (!result.Succeeded)
               return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "Error", Message = "User creation failed! Please check user details and try again." });

           return Ok(new Response { Status = "Success", Message = "User created successfully!" });
       }


       //[Authorize(Roles = "Admin")]
       [HttpPost]
       [Route("register-admin")]
       public async Task<IActionResult> RegisterAdmin([FromBody] RegisterModel model)
       {
           var userExists = await _userManager.FindByNameAsync(model.Username);
           if (userExists != null)
               return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "Error", Message = "User already exists!" });

           GrdbUser user = new()
           {
               Email = model.Email,
               SecurityStamp = Guid.NewGuid().ToString(),
               UserName = model.Username
           };
           var result = await _userManager.CreateAsync(user, model.Password);
           if (!result.Succeeded)
               return StatusCode(StatusCodes.Status500InternalServerError, new Response { Status = "Error", Message = "User creation failed! Please check user details and try again." });

           if (!await _roleManager.RoleExistsAsync(UserRoles.Admin))
               await _roleManager.CreateAsync(new IdentityRole<int>(UserRoles.Admin));
           if (!await _roleManager.RoleExistsAsync(UserRoles.User))
               await _roleManager.CreateAsync(new IdentityRole<int>(UserRoles.User));

           if (await _roleManager.RoleExistsAsync(UserRoles.Admin))
           {
               await _userManager.AddToRoleAsync(user, UserRoles.Admin);
           }
           if (await _roleManager.RoleExistsAsync(UserRoles.Admin))
           {
               await _userManager.AddToRoleAsync(user, UserRoles.User);
           }
           return Ok(new Response { Status = "Success", Message = "User created successfully!" });
       }

       private JwtSecurityToken GetToken(List<Claim> authClaims)
       {
           var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:SecretKey"]));
           var algorithm = SecurityAlgorithms.HmacSha256;
           if (key.KeySize < 256)
           {
               // Generate a new key with the required size (128 bits)
               var newKey = new byte[256 / 8];
               new RNGCryptoServiceProvider().GetBytes(newKey);
               key = new SymmetricSecurityKey(newKey);
           }

           var creds = new SigningCredentials(key, algorithm);
           var token = new JwtSecurityToken(
               issuer: _configuration["JWT:ValidIssuer"],
               audience: _configuration["JWT:ValidAudience"],
               claims: authClaims,
               expires: DateTime.UtcNow.AddHours(24),
               signingCredentials: creds);

           return token;

       }

Then i swagger i can create an user and then upon login i get this :
swagger login
Then i use the token to Authorize Swagger and get authorized,but when i am trying to use a Post endpoint that need authorization i get this :
swagger_post
I have also tried to login and make HTTP requests (with headers) from a React app and from a Blazor app. The login works but the requests provide the same error.
Maybe usefull information : both the API and the SQL server run inside a multi project docker container using docker compose. I use for the registered users the tables that Asp.net Core Identity created.

Can someone please help me figure out what am i doing wrong! Thank you in advance!

tried different ways to setup jwt authentication and different ways to generate tokens, but failed

New contributor

Luca Ionut is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật