feat: harden auth ops and deployment baseline
This commit is contained in:
+26
-6
@@ -4,6 +4,7 @@ using System.Text.Encodings.Web;
|
||||
using System.Text.Unicode;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.HttpOverrides;
|
||||
using Microsoft.AspNetCore.ResponseCompression;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MudBlazor.Services;
|
||||
@@ -12,16 +13,23 @@ using TaxBaik.Infrastructure;
|
||||
using TaxBaik.Web.Services;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
var isProduction = builder.Environment.IsProduction();
|
||||
|
||||
// Controllers (API)
|
||||
builder.Services.AddControllers();
|
||||
builder.Services.AddProblemDetails();
|
||||
builder.Services.AddHealthChecks();
|
||||
|
||||
// Razor Pages + Blazor Server 통합
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddRazorComponents().AddInteractiveServerComponents();
|
||||
|
||||
// JWT 인증
|
||||
var connectionString = builder.Configuration.GetConnectionString("Default")
|
||||
?? throw new InvalidOperationException("Missing connection string");
|
||||
var jwtKey = builder.Configuration["Jwt:SecretKey"] ?? throw new InvalidOperationException("Missing JWT SecretKey");
|
||||
if (isProduction && jwtKey.Contains("dev-secret", StringComparison.OrdinalIgnoreCase))
|
||||
throw new InvalidOperationException("Production JWT SecretKey must not use the development default.");
|
||||
var key = Encoding.ASCII.GetBytes(jwtKey);
|
||||
|
||||
builder.Services.AddAuthentication(opts =>
|
||||
@@ -35,8 +43,12 @@ builder.Services.AddAuthentication(opts =>
|
||||
{
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(key),
|
||||
ValidateIssuer = false,
|
||||
ValidateAudience = false
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = "taxbaik-admin",
|
||||
ValidateAudience = true,
|
||||
ValidAudience = "taxbaik-admin-client",
|
||||
ValidateLifetime = true,
|
||||
ClockSkew = TimeSpan.FromMinutes(1)
|
||||
};
|
||||
});
|
||||
|
||||
@@ -46,6 +58,7 @@ builder.Services.AddScoped<CustomAuthenticationStateProvider>();
|
||||
builder.Services.AddScoped<AuthenticationStateProvider>(sp => sp.GetRequiredService<CustomAuthenticationStateProvider>());
|
||||
builder.Services.AddScoped<ILocalStorageService, LocalStorageService>();
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
builder.Services.AddAuthorization();
|
||||
builder.Services.AddAuthorizationCore();
|
||||
|
||||
// HTTP Client for API
|
||||
@@ -82,21 +95,27 @@ builder.Services.AddSingleton(versionInfo);
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||
{
|
||||
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
||||
});
|
||||
|
||||
// Run migrations on startup (non-blocking for development)
|
||||
try
|
||||
{
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var connectionFactory = scope.ServiceProvider.GetRequiredService<TaxBaik.Domain.Interfaces.IDbConnectionFactory>();
|
||||
var cs = builder.Configuration.GetConnectionString("Default")
|
||||
?? throw new InvalidOperationException("Missing connection string");
|
||||
var migrationRunner = new TaxBaik.Infrastructure.Data.MigrationRunner(cs, connectionFactory);
|
||||
var migrationRunner = new TaxBaik.Infrastructure.Data.MigrationRunner(connectionString, connectionFactory);
|
||||
await migrationRunner.RunAsync();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"⚠️ Migration warning (non-blocking): {ex.Message}");
|
||||
if (!app.Environment.IsDevelopment())
|
||||
throw;
|
||||
|
||||
Console.WriteLine($"Migration warning (development only): {ex.Message}");
|
||||
}
|
||||
|
||||
app.UsePathBase("/taxbaik");
|
||||
@@ -115,6 +134,7 @@ if (!app.Environment.IsDevelopment())
|
||||
|
||||
// API + Razor Pages + Blazor 매핑
|
||||
app.MapControllers();
|
||||
app.MapHealthChecks("/healthz");
|
||||
app.MapRazorPages();
|
||||
app.MapRazorComponents<TaxBaik.Web.Components.Admin.App>().AddInteractiveServerRenderMode();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user