2026-04-13 21:36:02 -03:00
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
2026-04-14 13:28:36 -03:00
|
|
|
using Microsoft.AspNetCore.Http;
|
2026-04-13 21:36:02 -03:00
|
|
|
using Microsoft.Extensions.Configuration;
|
|
|
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using Microsoft.Extensions.Options;
|
|
|
|
|
using Microsoft.IdentityModel.Tokens;
|
|
|
|
|
using SIGCM2.Application.Abstractions;
|
|
|
|
|
using SIGCM2.Application.Abstractions.Persistence;
|
|
|
|
|
using SIGCM2.Application.Abstractions.Security;
|
2026-04-14 13:28:36 -03:00
|
|
|
using SIGCM2.Application.Auth;
|
|
|
|
|
using SIGCM2.Infrastructure.Http;
|
2026-04-13 21:36:02 -03:00
|
|
|
using SIGCM2.Infrastructure.Messaging;
|
|
|
|
|
using SIGCM2.Infrastructure.Persistence;
|
|
|
|
|
using SIGCM2.Infrastructure.Security;
|
|
|
|
|
|
|
|
|
|
namespace SIGCM2.Infrastructure;
|
|
|
|
|
|
|
|
|
|
public static class DependencyInjection
|
|
|
|
|
{
|
|
|
|
|
public static IServiceCollection AddInfrastructure(
|
|
|
|
|
this IServiceCollection services,
|
|
|
|
|
IConfiguration configuration)
|
|
|
|
|
{
|
|
|
|
|
// Database
|
|
|
|
|
var connectionString = configuration.GetConnectionString("SqlServer")
|
|
|
|
|
?? throw new InvalidOperationException("Missing ConnectionStrings:SqlServer");
|
|
|
|
|
services.AddSingleton(new SqlConnectionFactory(connectionString));
|
|
|
|
|
services.AddScoped<IUsuarioRepository, UsuarioRepository>();
|
2026-04-14 13:28:36 -03:00
|
|
|
services.AddScoped<IRefreshTokenRepository, RefreshTokenRepository>();
|
2026-04-13 21:36:02 -03:00
|
|
|
|
|
|
|
|
// JWT Options — bound lazily via IOptions so tests can override via ConfigureWebHost
|
|
|
|
|
services.Configure<JwtOptions>(configuration.GetSection("Jwt"));
|
|
|
|
|
// Also expose as JwtOptions directly for convenience (resolves via IOptions<JwtOptions>)
|
|
|
|
|
services.AddSingleton<JwtOptions>(sp => sp.GetRequiredService<IOptions<JwtOptions>>().Value);
|
|
|
|
|
|
2026-04-14 13:28:36 -03:00
|
|
|
// AuthOptions (Application layer) — populated from the same Jwt config section
|
|
|
|
|
services.AddSingleton<AuthOptions>(sp =>
|
|
|
|
|
{
|
|
|
|
|
var opts = sp.GetRequiredService<JwtOptions>();
|
|
|
|
|
return new AuthOptions
|
|
|
|
|
{
|
|
|
|
|
AccessTokenMinutes = opts.AccessTokenMinutes,
|
|
|
|
|
RefreshTokenDays = opts.RefreshTokenDays,
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
2026-04-13 21:36:02 -03:00
|
|
|
// RSA key pair — loaded lazily as singletons from the fully-resolved JwtOptions
|
|
|
|
|
services.AddSingleton<RSA>(sp =>
|
|
|
|
|
{
|
|
|
|
|
var opts = sp.GetRequiredService<JwtOptions>();
|
|
|
|
|
return RsaKeyLoader.LoadPrivateKey(opts);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
services.AddSingleton<RsaSecurityKey>(sp =>
|
|
|
|
|
{
|
|
|
|
|
var opts = sp.GetRequiredService<JwtOptions>();
|
|
|
|
|
return new RsaSecurityKey(RsaKeyLoader.LoadPublicKey(opts));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
services.AddScoped<IJwtService>(sp =>
|
|
|
|
|
new JwtService(sp.GetRequiredService<RSA>(), sp.GetRequiredService<JwtOptions>()));
|
|
|
|
|
services.AddScoped<IPasswordHasher, BcryptPasswordHasher>();
|
2026-04-14 13:28:36 -03:00
|
|
|
services.AddSingleton<IRefreshTokenGenerator, RefreshTokenGenerator>();
|
|
|
|
|
services.AddHttpContextAccessor();
|
|
|
|
|
services.AddScoped<IClientContext, ClientContext>();
|
2026-04-13 21:36:02 -03:00
|
|
|
|
|
|
|
|
// Dispatcher
|
|
|
|
|
services.AddScoped<IDispatcher, Dispatcher>();
|
|
|
|
|
|
|
|
|
|
// JWT Bearer authentication
|
|
|
|
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
|
|
|
|
.AddJwtBearer();
|
|
|
|
|
|
|
|
|
|
// Post-configure JWT Bearer — wire RSA public key + validation params from resolved options
|
|
|
|
|
services.AddOptions<JwtBearerOptions>(JwtBearerDefaults.AuthenticationScheme)
|
|
|
|
|
.PostConfigure<RsaSecurityKey, JwtOptions>((jwtBearerOpts, rsaKey, jwtOpts) =>
|
|
|
|
|
{
|
|
|
|
|
jwtBearerOpts.TokenValidationParameters = new TokenValidationParameters
|
|
|
|
|
{
|
|
|
|
|
ValidateIssuerSigningKey = true,
|
|
|
|
|
IssuerSigningKey = rsaKey,
|
|
|
|
|
ValidateIssuer = true,
|
|
|
|
|
ValidIssuer = jwtOpts.Issuer,
|
|
|
|
|
ValidateAudience = true,
|
|
|
|
|
ValidAudience = jwtOpts.Audience,
|
|
|
|
|
ValidateLifetime = true,
|
|
|
|
|
ClockSkew = TimeSpan.Zero
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return services;
|
|
|
|
|
}
|
|
|
|
|
}
|