using ChatbotApi.Data.Models; using DotNetEnv; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.RateLimiting; using Microsoft.IdentityModel.Tokens; using System.Text; using System.Threading.RateLimiting; using Microsoft.AspNetCore.Identity; using Microsoft.OpenApi.Models; // Cargar variables de entorno desde el archivo .env Env.Load(); var builder = WebApplication.CreateBuilder(args); // Definimos una política de CORS para permitir solicitudes desde nuestro frontend de Vite var myAllowSpecificOrigins = "_myAllowSpecificOrigins"; builder.Services.AddCors(options => { options.AddPolicy(name: myAllowSpecificOrigins, policy => { policy.WithOrigins("http://192.168.5.129:8081", "http://192.168.5.129:8082", "http://localhost:5173", "http://localhost:5174") .AllowAnyHeader() .AllowAnyMethod(); }); }); // 1. Añadimos el DbContext para Entity Framework var connectionString = builder.Configuration.GetConnectionString("DefaultConnection"); builder.Services.AddDbContext(options => options.UseSqlServer(connectionString)); // 2. Añadimos ASP.NET Core Identity builder.Services.AddIdentity(options => { options.Password.RequireDigit = true; options.Password.RequiredLength = 8; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = true; options.Password.RequireLowercase = false; }) .AddEntityFrameworkStores() .AddDefaultTokenProviders(); builder.Services.AddMemoryCache(); // =========== INICIO DE CONFIGURACIÓN JWT =========== 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 = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes( builder.Configuration["Jwt:Key"] ?? throw new InvalidOperationException("La clave JWT no está configurada.") )) }; }); // RATE LIMITING builder.Services.AddRateLimiter(options => { options.AddFixedWindowLimiter(policyName: "fixed", limiterOptions => { limiterOptions.PermitLimit = 10; // Permitir 10 peticiones... limiterOptions.Window = TimeSpan.FromMinutes(1); // ...por cada minuto. limiterOptions.QueueLimit = 2; // Poner en cola hasta 2 peticiones si se excede el límite brevemente. limiterOptions.QueueProcessingOrder = QueueProcessingOrder.OldestFirst; }); // Esta función se ejecuta cuando una petición es rechazada options.RejectionStatusCode = StatusCodes.Status429TooManyRequests; }); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(options => { options.SwaggerDoc("v1", new OpenApiInfo { Title = "Chatbot API", Version = "v1" }); options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme { In = ParameterLocation.Header, Description = "Por favor, introduce 'Bearer' seguido de un espacio y el token JWT", Name = "Authorization", Type = SecuritySchemeType.ApiKey, Scheme = "Bearer" }); options.AddSecurityRequirement(new OpenApiSecurityRequirement { { new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" } }, new string[] {} } }); }); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); // =========== CONFIGURACIÓN Y USO DEL MIDDLEWARE DE ENCABEZADOS DE SEGURIDAD =========== app.UseSecurityHeaders(policy => { policy.AddDefaultSecurityHeaders(); // Añade los encabezados por defecto policy.AddContentSecurityPolicy(builder => { builder.AddDefaultSrc().Self(); // Permisos necesarios para Swagger UI builder.AddScriptSrc().Self().UnsafeInline(); builder.AddStyleSrc().Self().UnsafeInline(); }); }); app.UseCors(myAllowSpecificOrigins); app.UseRateLimiter(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run();