Enhance logging and refactor configuration in API

Updated `EnvelopeGenerator.GeneratorAPI.csproj` to include NLog packages for improved logging.
This commit is contained in:
Developer 02 2025-05-10 01:24:24 +02:00
parent 171de98552
commit 00fedc7c4c
2 changed files with 159 additions and 140 deletions

View File

@ -23,6 +23,8 @@
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" /> <PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" /> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" />
<PackageReference Include="NLog" Version="5.2.5" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
<PackageReference Include="Scalar.AspNetCore" Version="2.2.1" /> <PackageReference Include="Scalar.AspNetCore" Version="2.2.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" /> <PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" /> <PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />

View File

@ -16,19 +16,30 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens; using Microsoft.IdentityModel.Tokens;
using DigitalData.Core.Abstractions.Security.Extensions; using DigitalData.Core.Abstractions.Security.Extensions;
using EnvelopeGenerator.GeneratorAPI.Middleware; using EnvelopeGenerator.GeneratorAPI.Middleware;
using NLog.Web;
using NLog;
var builder = WebApplication.CreateBuilder(args); var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("Logging initialized!");
var config = builder.Configuration; try
{
var builder = WebApplication.CreateBuilder(args);
var deferredProvider = new DeferredServiceProvider(); builder.Logging.ClearProviders();
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
builder.Host.UseNLog();
builder.Services.AddControllers(); var config = builder.Configuration;
//CORS Policy var deferredProvider = new DeferredServiceProvider();
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
builder.Services.AddControllers();
//CORS Policy
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
throw new InvalidOperationException("AllowedOrigins section is missing in the configuration."); throw new InvalidOperationException("AllowedOrigins section is missing in the configuration.");
builder.Services.AddCors(options => builder.Services.AddCors(options =>
{ {
options.AddPolicy("AllowSpecificOriginsPolicy", builder => options.AddPolicy("AllowSpecificOriginsPolicy", builder =>
{ {
@ -40,10 +51,10 @@ builder.Services.AddCors(options =>
}); });
}); });
// Swagger // Swagger
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options => builder.Services.AddSwaggerGen(options =>
{ {
options.SwaggerDoc("v1", new OpenApiInfo options.SwaggerDoc("v1", new OpenApiInfo
{ {
Version = "v1", Version = "v1",
@ -87,24 +98,24 @@ builder.Services.AddSwaggerGen(options =>
{ {
options.IncludeXmlComments(xmlFile); options.IncludeXmlComments(xmlFile);
} }
}); });
builder.Services.AddOpenApi(); builder.Services.AddOpenApi();
// DbContext // DbContext
var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json."); var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
builder.Services.Configure<ConnectionString>(cs => cs.Value = connStr); builder.Services.Configure<ConnectionString>(cs => cs.Value = connStr);
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr)); builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams")); builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
var authTokenKeys = config.GetOrDefault<AuthTokenKeys>(); var authTokenKeys = config.GetOrDefault<AuthTokenKeys>();
builder.Services.AddAuthentication(options => builder.Services.AddAuthentication(options =>
{ {
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}) })
.AddJwtBearer(opt => .AddJwtBearer(opt =>
{ {
opt.TokenValidationParameters = new TokenValidationParameters opt.TokenValidationParameters = new TokenValidationParameters
@ -139,73 +150,79 @@ builder.Services.AddAuthentication(options =>
}; };
}); });
// Authentication // Authentication
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie(options => .AddCookie(options =>
{ {
options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only
options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites
options.LoginPath = "/api/auth/login"; options.LoginPath = "/api/auth/login";
options.LogoutPath = "/api/auth/logout"; options.LogoutPath = "/api/auth/logout";
options.SlidingExpiration = true; options.SlidingExpiration = true;
}); });
// User manager // User manager
builder.Services.AddUserManager<EGDbContext>(); builder.Services.AddUserManager<EGDbContext>();
// LDAP // LDAP
builder.ConfigureBySection<DirectorySearchOptions>(); builder.ConfigureBySection<DirectorySearchOptions>();
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions")); builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
// Localizer // Localizer
builder.Services.AddCookieBasedLocalizer() ; builder.Services.AddCookieBasedLocalizer();
// Envelope generator serives // Envelope generator serives
builder.Services builder.Services
.AddEnvelopeGeneratorInfrastructureServices(sqlExecutorConfigureOptions: executor => executor.ConnectionString = connStr) .AddEnvelopeGeneratorInfrastructureServices(sqlExecutorConfigureOptions: executor => executor.ConnectionString = connStr)
.AddEnvelopeGeneratorServices(config); .AddEnvelopeGeneratorServices(config);
var app = builder.Build(); var app = builder.Build();
deferredProvider.Factory = () => app.Services; deferredProvider.Factory = () => app.Services;
app.UseMiddleware<ExceptionHandlingMiddleware>(); app.UseMiddleware<ExceptionHandlingMiddleware>();
app.MapOpenApi(); app.MapOpenApi();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment() || (app.IsDevOrDiP() && config.GetValue<bool>("UseSwagger"))) if (app.Environment.IsDevelopment() || (app.IsDevOrDiP() && config.GetValue<bool>("UseSwagger")))
{ {
app.UseSwagger(); app.UseSwagger();
app.UseSwaggerUI(); app.UseSwaggerUI();
app.MapScalarApiReference(); app.MapScalarApiReference();
} }
// Set CORS policy // Set CORS policy
app.UseCors("AllowSpecificOriginsPolicy"); app.UseCors("AllowSpecificOriginsPolicy");
// Localizer // Localizer
string[] supportedCultureNames = { "de-DE", "en-US" }; string[] supportedCultureNames = { "de-DE", "en-US" };
IList<CultureInfo> list = supportedCultureNames.Select((string cn) => new CultureInfo(cn)).ToList(); IList<CultureInfo> list = supportedCultureNames.Select((string cn) => new CultureInfo(cn)).ToList();
CultureInfo cultureInfo = list.FirstOrDefault() ?? throw new ArgumentNullException("supportedCultureNames", "Supported cultures cannot be empty."); CultureInfo cultureInfo = list.FirstOrDefault() ?? throw new ArgumentNullException("supportedCultureNames", "Supported cultures cannot be empty.");
RequestLocalizationOptions requestLocalizationOptions = new RequestLocalizationOptions RequestLocalizationOptions requestLocalizationOptions = new RequestLocalizationOptions
{ {
SupportedCultures = list, SupportedCultures = list,
SupportedUICultures = list SupportedUICultures = list
}; };
requestLocalizationOptions.RequestCultureProviders.Add(new QueryStringRequestCultureProvider()); requestLocalizationOptions.RequestCultureProviders.Add(new QueryStringRequestCultureProvider());
app.UseRequestLocalization(requestLocalizationOptions); app.UseRequestLocalization(requestLocalizationOptions);
app.UseHttpsRedirection(); app.UseHttpsRedirection();
app.UseDefaultFiles(); app.UseDefaultFiles();
app.UseStaticFiles(); app.UseStaticFiles();
app.UseAuthentication(); app.UseAuthentication();
app.UseAuthorization(); app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.Run(); app.Run();
}
catch (Exception ex)
{
logger.Error(ex, "Stopped program because of exception");
throw;
}