using Expenses.Data;
using expensesBE.Data.DTO.Interfaces;
using expensesBE.Data.DTO;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
var builder = WebApplication.CreateBuilder(args);
var jwtIssuer = Environment.GetEnvironmentVariable("JWT_ISSUER");
var jwtSecret = Environment.GetEnvironmentVariable("JWT_SECRET");
var jwtAudience = Environment.GetEnvironmentVariable("JWT_AUDIENCE");
if (string.IsNullOrEmpty(jwtIssuer) || string.IsNullOrEmpty(jwtSecret) || string.IsNullOrEmpty(jwtAudience))
{
throw new ArgumentNullException("JWT configuration is missing");
}
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(connectionString));
// Configura Identity
builder.Services.AddDefaultIdentity<IdentityUser>(options =>
{
options.SignIn.RequireConfirmedAccount = true;
}).AddRoles<IdentityRole>()
.AddEntityFrameworkStores<AppDbContext>();
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = jwtIssuer,
ValidAudience = jwtIssuer,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSecret))
};
});
builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IExpensesServices, ExpensesServices>();
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddCors(options =>
{
options.AddPolicy("AllowAllOrigins", builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddControllersWithViews();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseSwagger(); // Enable Swagger
app.UseSwaggerUI(); // Enable Swagger UI
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseCors("AllowAllOrigins");
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.MapControllers();
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}"
);
app.Run();
ASP.NET Core JWT Authentication Returning Unauthorized(invalid-token 401) for Authenticated Requests in Controller Actions
Hi everyone,
I'm encountering an issue with JWT authentication in my ASP.NET Core 8.0 application. While the token generation and authentication seem to work correctly in my AuthenticationController
, any requests to other controllers requiring authorization are returning 401 Unauthorized
.
The JWT token is generated and validated successfully in the AuthenticationController
. However, when I try to access other controllers that require authorization, I receive a 401 Unauthorized
response. The JWT issuer, audience, and secret are configured correctly in Azure and are being used successfully in the AuthenticationController
.
For testing purposes, I added the action that I want to use in the other controller (which doesn't work) inside the AuthenticationController
, and it works even without the [Authorize]
attribute on that controller.
4 answers
Sort by: Most helpful
-
Antonio Simonetti 0 Reputation points
2024-07-24T16:04:49.0933333+00:00 -
Bruce (SqlWork.com) 66,461 Reputation points
2024-07-24T21:22:58.0666667+00:00 authentication is only required if you specify that controller needs authentication. when your javascript ajax calls the controller is it passing the bearer token?
const rs = await fetch( url, { headers: {Authorization: `Bearer ${token}`} }).then(resp => resp.json());
-
SurferOnWww 3,041 Reputation points
2024-07-25T01:39:13.94+00:00 Please try the followings. If you could complete (1) through (7) I will add the description and code to generate the JWT required for authentication, send the JWT to the API and obtain the JSON response
(1) Create project
Use template of Visual Studio 2022. Select the ASP.NET Core Web API:
Set the Authentication type to none:
(2) Install NuGet package
Install the Microsoft.AspNetCore.Authentication.JwtBearer:
(3) Register JWT Authntocation
Open the Program.cs and add the service and middleware for the JWT-based authentication, as follows:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; namespace WebApiJwtCors { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Add service for JWT-based authentication builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!)) }; }); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); // Add middleware for JWT-based authentication app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); } } }
(4) Add Key and Issuer
Add Jwt element to the appsettings.json so that the TokenValidationParameters constractor in the above (3) code can obtain the values of Key and Issuer:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*", "Jwt": { "Key": "veryVerySecretKeyWhichMustBeLongerThan32", "Issuer": "https://localhost:44344" } }
(5) Add CORS, only if required
Open the Program.cs and add the service and middleware for the CORS as follows:
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; namespace WebApiJwtCors { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); // Add services to the container. // Add service for CORS var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; builder.Services.AddCors(options => { options.AddPolicy(name: MyAllowSpecificOrigins, policy => { policy.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); }); }); // Add service for JWT-based authentication builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Issuer"], IssuerSigningKey = new SymmetricSecurityKey( Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]!)) }; }); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); // Add middleware for CORS app.UseCors(MyAllowSpecificOrigins); // Add middleware for JWT-based authentication app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); } }
(6) Build and confirm
Confirm that the WeatherForecast controller returns the JSON response as expected:
(7) Add [Authorize] attribute
Add [Authorize] attribute to the Get() method of WeatherForecastController as shown below:
Confirm that the WeatherForecast controller returns HTTP 401 Unauthorized response:
-
SurferOnWww 3,041 Reputation points
2024-07-25T03:21:53.3566667+00:00 deleted because duplicated