I am building an API with .NET 6 but I am stuck with this error. I get a token with login then I added that token to header but there is always getting 401: Unauthorized error.
NOTE: I am getting Bearer error="invalid_token" but there is no description.
This is my code;
Program.cs:
using Autofac; using Autofac.Extensions.DependencyInjection; using Business.DependencyResolvers.Autofac; using Core.Utilities.Security.Encryption; using Core.Utilities.Security.Jwt; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Autofac builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory()); builder.Host.ConfigureContainer<ContainerBuilder>(builder => builder.RegisterModule(new AutofacBusinessModule())); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "OzkanOner", Version = "v1" }); c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() { Name = "Authorization", Type = SecuritySchemeType.ApiKey, Scheme = "Bearer", BearerFormat = "JWT", In = ParameterLocation.Header, Description = "JWT Authorization header using the Bearer scheme." }); c.AddSecurityRequirement(new OpenApiSecurityRequirement{ { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] {} } }); }); //CORS builder.Services.AddCors(options => { options.AddPolicy("AllowOrigin", builder => builder.WithOrigins("http://localhost:4200")); }); var tokenOptions = builder.Configuration.GetSection("TokenOptions").Get<TokenOptions>(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidIssuer = tokenOptions.Issuer, ValidAudience = tokenOptions.Audience, ValidateIssuerSigningKey = true, IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey) }; }); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseCors(builder => builder.WithOrigins("http://localhost:4200").AllowAnyHeader()); app.UseHttpsRedirection(); // Authentication & Authorization app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); JwtHelper.cs:
using Core.Entities.Concrete; using Core.Extensions; using Core.Utilities.Security.Encryption; using Microsoft.Extensions.Configuration; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; namespace Core.Utilities.Security.Jwt { public class JwtHelper : ITokenHelper { public IConfiguration Configuration { get; } private TokenOptions _tokenOptions; private DateTime _accessTokenExpiration; public JwtHelper(IConfiguration configuration) { Configuration = configuration; _tokenOptions = Configuration.GetSection("TokenOptions").Get<TokenOptions>(); } public AccessToken CreateToken(User user, List<OperationClaim> operationClaims) { _accessTokenExpiration = DateTime.Now.AddMinutes(_tokenOptions.AccessTokenExpiration); var securityKey = SecurityKeyHelper.CreateSecurityKey(_tokenOptions.SecurityKey); var signingCredentials = SigningCredentialsHelper.CreateSigningCredentials(securityKey); var jwt = CreateJwtSecurityToken(_tokenOptions, user, signingCredentials, operationClaims); var jwtSecurityTokenHandler = new JwtSecurityTokenHandler(); var token = jwtSecurityTokenHandler.WriteToken(jwt); return new AccessToken { Token = token, Expiration = _accessTokenExpiration }; } public JwtSecurityToken CreateJwtSecurityToken(TokenOptions tokenOptions, User user, SigningCredentials signingCredentials, List<OperationClaim> operationClaims) { var jwt = new JwtSecurityToken( issuer: tokenOptions.Issuer, audience: tokenOptions.Audience, expires: _accessTokenExpiration, notBefore: DateTime.Now, claims: SetClaims(user, operationClaims), signingCredentials: signingCredentials ); return jwt; } private IEnumerable<Claim> SetClaims(User user, List<OperationClaim> operationClaims) { var claims = new List<Claim>(); claims.AddNameIdentifier(user.Id.ToString()); claims.AddEmail(user.Email); claims.AddName($"{user.FirstName} {user.LastName}"); claims.AddRoles(operationClaims.Select(c => c.Name).ToArray()); return claims; } } } appsettings.json:
{ "TokenOptions": { "Audience": "https://localhost:7047", "Issuer": "https://localhost:7047", "AccessTokenExpiration": 60, "SecurityKey": "ASD89ays7fhHASDF09ua0sdu6d32ghbjlka" }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" }