diff --git a/src/Managing.Api/Authorization/JwtMiddleware.cs b/src/Managing.Api/Authorization/JwtMiddleware.cs
deleted file mode 100644
index 18617e6..0000000
--- a/src/Managing.Api/Authorization/JwtMiddleware.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-using Managing.Application.Abstractions.Services;
-
-namespace Managing.Api.Authorization;
-
-public class JwtMiddleware
-{
- private readonly RequestDelegate _next;
-
- public JwtMiddleware(RequestDelegate next, IConfiguration config)
- {
- _next = next;
- }
-
- public async Task Invoke(HttpContext context, IUserService userService, IJwtUtils jwtUtils)
- {
- if (context.Request.Path.StartsWithSegments("/User/create-token") ||
- context.Request.Path.StartsWithSegments("/swagger") ||
- context.Request.Path.StartsWithSegments("/health"))
- {
- await _next(context);
- return;
- }
-
- var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
-
- if (string.IsNullOrEmpty(token))
- {
- throw new UnauthorizedAccessException("Authorization token is missing");
- }
-
- var userId = jwtUtils.ValidateJwtToken(token);
- if (userId != null)
- {
- // attach user to context on successful jwt validation
- context.Items["User"] = await userService.GetUserByAddressAsync(userId);
- }
-
- await _next(context);
- }
-}
\ No newline at end of file
diff --git a/src/Managing.Api/Controllers/DataController.cs b/src/Managing.Api/Controllers/DataController.cs
index 3146c82..07aa3d3 100644
--- a/src/Managing.Api/Controllers/DataController.cs
+++ b/src/Managing.Api/Controllers/DataController.cs
@@ -554,7 +554,6 @@ public class DataController : ControllerBase
}
-
///
/// Retrieves a paginated list of agent summaries for the agent index page
///
@@ -564,6 +563,7 @@ public class DataController : ControllerBase
/// Sort order - "asc" or "desc" (defaults to "desc")
/// Optional comma-separated list of agent names to filter by
/// A paginated list of agent summaries sorted by the specified field
+ [AllowAnonymous]
[HttpGet("GetAgentIndexPaginated")]
public async Task> GetAgentIndexPaginated(
int page = 1,
diff --git a/src/Managing.Api/Program.cs b/src/Managing.Api/Program.cs
index 0e323de..ec2079f 100644
--- a/src/Managing.Api/Program.cs
+++ b/src/Managing.Api/Program.cs
@@ -1,9 +1,11 @@
+using System.Security.Claims;
using System.Text;
using System.Text.Json.Serialization;
using HealthChecks.UI.Client;
using Managing.Api.Authorization;
using Managing.Api.Filters;
using Managing.Api.HealthChecks;
+using Managing.Application.Abstractions.Services;
using Managing.Application.Hubs;
using Managing.Bootstrap;
using Managing.Common;
@@ -155,20 +157,70 @@ builder.Services.Configure(builder.Configuration.GetSection(Const
builder.Services.AddControllers().AddJsonOptions(options =>
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
-builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(o =>
-{
- o.SaveToken = true;
- o.TokenValidationParameters = new TokenValidationParameters
+builder.Services
+ .AddAuthentication(options =>
{
- ValidIssuer = builder.Configuration["Authentication:Schemes:Bearer:ValidIssuer"],
- ValidAudience = builder.Configuration["Authentication:Schemes:Bearer:ValidAudiences"],
- IssuerSigningKey = new SymmetricSecurityKey
- (Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"])),
- ValidateIssuer = false,
- ValidateAudience = false,
- ValidateIssuerSigningKey = true
- };
-});
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ })
+ .AddJwtBearer(o =>
+ {
+ o.SaveToken = true;
+ o.TokenValidationParameters = new TokenValidationParameters
+ {
+ ValidIssuer = builder.Configuration["Authentication:Schemes:Bearer:ValidIssuer"],
+ ValidAudience = builder.Configuration["Authentication:Schemes:Bearer:ValidAudiences"],
+ IssuerSigningKey = new SymmetricSecurityKey
+ (Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Secret"])),
+ ValidateIssuer = false,
+ ValidateAudience = false,
+ ValidateIssuerSigningKey = true
+ };
+ o.Events = new JwtBearerEvents
+ {
+ OnMessageReceived = context =>
+ {
+ // If you want to get the token from a custom header or query string
+ // var accessToken = context.Request.Query["access_token"];
+ // if (!string.IsNullOrEmpty(accessToken) &&
+ // context.HttpContext.Request.Path.StartsWithSegments("/hub"))
+ // {
+ // context.Token = accessToken;
+ // }
+ return Task.CompletedTask;
+ },
+ OnAuthenticationFailed = context =>
+ {
+ if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
+ {
+ context.Response.Headers.Add("Token-Expired", "true");
+ }
+
+ return Task.CompletedTask;
+ },
+ // --- IMPORTANT: Attach User to Context Here ---
+ OnTokenValidated = async context =>
+ {
+ var userService = context.HttpContext.RequestServices.GetRequiredService();
+ // Assuming your JWT token contains a 'nameid' claim (or similar) for the user ID
+ var userId = context.Principal.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+
+ if (!string.IsNullOrEmpty(userId))
+ {
+ // Fetch the full user object from your service
+ var user = await userService.GetUserByAddressAsync(userId);
+ if (user != null)
+ {
+ // Attach the user object to HttpContext.Items
+ context.HttpContext.Items["User"] = user;
+ }
+ }
+
+ await Task.CompletedTask;
+ }
+ // --- END IMPORTANT ---
+ };
+ });
builder.Services.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
{
@@ -251,14 +303,9 @@ app.UseSentryDiagnostics();
// Using shared GlobalErrorHandlingMiddleware from core project
app.UseMiddleware();
-app.UseMiddleware();
-
app.UseHttpsRedirection();
-
app.UseRouting();
-
app.UseAuthentication();
-
app.UseAuthorization();
app.UseEndpoints(endpoints =>
@@ -280,5 +327,4 @@ app.UseEndpoints(endpoints =>
});
});
-
app.Run();
\ No newline at end of file