Files
Claude 78612ea29d
Some checks failed
CI / build-backend (pull_request) Failing after 1m12s
CI / build-frontend (pull_request) Successful in 28s
feat: implement authentication system for API Gateway and FileService
- Add JWT Bearer token validation to API Gateway with restricted CORS
- Add cookie-based JWT validation to FileService for browser image requests
- Create shared authentication infrastructure in FictionArchive.Service.Shared
- Update frontend to set fa_session cookie after OIDC login
- Add [Authorize] attributes to GraphQL mutations with role-based restrictions
- Configure OIDC settings for both services in docker-compose

Implements FA-17: Authentication for microservices architecture
2025-11-27 14:05:54 +00:00

76 lines
2.5 KiB
C#

using Amazon.Runtime;
using Amazon.S3;
using FictionArchive.Common.Extensions;
using FictionArchive.Service.FileService.Models;
using FictionArchive.Service.FileService.Models.IntegrationEvents;
using FictionArchive.Service.FileService.Services.EventHandlers;
using FictionArchive.Service.Shared.Extensions;
using FictionArchive.Service.Shared.Services.EventBus.Implementations;
using Microsoft.Extensions.Options;
namespace FictionArchive.Service.FileService;
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.AddLocalAppsettings();
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHealthChecks();
#region Event Bus
builder.Services.AddRabbitMQ(opt =>
{
builder.Configuration.GetSection("RabbitMQ").Bind(opt);
})
.Subscribe<FileUploadRequestCreatedEvent, FileUploadRequestCreatedEventHandler>();
#endregion
// Add authentication with cookie support
builder.Services.AddOidcCookieAuthentication(builder.Configuration);
builder.Services.AddFictionArchiveAuthorization();
builder.Services.Configure<ProxyConfiguration>(builder.Configuration.GetSection("ProxyConfiguration"));
// Add S3 Client
builder.Services.Configure<S3Configuration>(builder.Configuration.GetSection("S3"));
builder.Services.AddSingleton<AmazonS3Client>(provider =>
{
var config = provider.GetRequiredService<IOptions<S3Configuration>>().Value;
var s3Config = new AmazonS3Config
{
ServiceURL = config.Url, // Garage endpoint
ForcePathStyle = true, // REQUIRED for Garage
AuthenticationRegion = "garage"
};
return new AmazonS3Client(
new BasicAWSCredentials(config.AccessKey, config.SecretKey),
s3Config);
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthentication();
app.UseAuthorization();
app.MapHealthChecks("/healthz");
app.MapControllers();
app.Run();
}
}