forked from gongxuegit/tiku-backend.net
feat: establish dotnet engineering foundation
This commit is contained in:
@@ -1,7 +1,42 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Tiku.Application.Security;
|
||||
|
||||
namespace Tiku.Api.Options;
|
||||
|
||||
public static class OptionsValidation
|
||||
{
|
||||
public const string DevelopmentSigningKey = "development-only-tiku-signing-key-change-before-production";
|
||||
|
||||
public static string ResolveDatabaseConnectionString(
|
||||
IConfiguration configuration,
|
||||
bool isDevelopment)
|
||||
{
|
||||
var connectionString =
|
||||
configuration.GetConnectionString("Database") ??
|
||||
configuration["DATABASE_URL"];
|
||||
if (!string.IsNullOrWhiteSpace(connectionString))
|
||||
{
|
||||
return connectionString;
|
||||
}
|
||||
|
||||
if (isDevelopment)
|
||||
{
|
||||
return $"Host=localhost;Database=tiku;Username={Environment.UserName}";
|
||||
}
|
||||
|
||||
throw new InvalidOperationException(
|
||||
"Database connection is required outside Development. Configure ConnectionStrings:Database or DATABASE_URL.");
|
||||
}
|
||||
|
||||
public static bool BeValidJwtOptions(JwtOptions options, bool isProduction)
|
||||
{
|
||||
return !isProduction ||
|
||||
!string.Equals(
|
||||
options.SigningKey,
|
||||
DevelopmentSigningKey,
|
||||
StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static bool BeValidCorsOptions(CorsOptions options)
|
||||
{
|
||||
if (options.AllowCredentials && options.AllowedOrigins.Length == 0)
|
||||
|
||||
@@ -17,6 +17,7 @@ using Tiku.Api.Security;
|
||||
using Tiku.Application;
|
||||
using Tiku.Application.Security;
|
||||
using Tiku.Infrastructure;
|
||||
using Tiku.Infrastructure.Commerce;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
using Tiku.Infrastructure.Storage;
|
||||
|
||||
@@ -133,10 +134,9 @@ try
|
||||
});
|
||||
}
|
||||
|
||||
var connectionString =
|
||||
builder.Configuration.GetConnectionString("Database") ??
|
||||
builder.Configuration["DATABASE_URL"] ??
|
||||
"Host=localhost;Database=tiku;Username=postgres";
|
||||
var connectionString = OptionsValidation.ResolveDatabaseConnectionString(
|
||||
builder.Configuration,
|
||||
builder.Environment.IsDevelopment());
|
||||
|
||||
builder.Services.AddInfrastructure(connectionString);
|
||||
builder.Services.Configure<ObjectStorageOptions>(
|
||||
@@ -172,10 +172,28 @@ try
|
||||
? useInternalEndpoint
|
||||
: options.UseInternalEndpoint;
|
||||
});
|
||||
builder.Services.AddOptions<TenantSecretEncryptionOptions>()
|
||||
.Bind(builder.Configuration.GetSection(TenantSecretEncryptionOptions.SectionName))
|
||||
.PostConfigure(options =>
|
||||
{
|
||||
options.KeyId = builder.Configuration["TIKU_TENANT_SECRET_KEY_ID"] ?? options.KeyId;
|
||||
options.MasterKey = builder.Configuration["TIKU_TENANT_SECRET_MASTER_KEY"] ?? options.MasterKey;
|
||||
})
|
||||
.Validate(
|
||||
TenantSecretEncryptionOptions.BeValid,
|
||||
"Tenant secret encryption requires a key ID and a base64-encoded 32-byte master key.")
|
||||
.Validate(
|
||||
options => !builder.Environment.IsProduction() ||
|
||||
!TenantSecretEncryptionOptions.IsDevelopmentDefault(options),
|
||||
"Production tenant secret encryption cannot use the development master key.")
|
||||
.ValidateOnStart();
|
||||
|
||||
builder.Services.AddOptions<JwtOptions>()
|
||||
.Bind(builder.Configuration.GetSection("Security:Jwt"))
|
||||
.ValidateDataAnnotations()
|
||||
.Validate(
|
||||
options => OptionsValidation.BeValidJwtOptions(options, builder.Environment.IsProduction()),
|
||||
"Production JWT signing key must be explicitly configured and cannot use the development key.")
|
||||
.ValidateOnStart();
|
||||
var jwtOptions = builder.Configuration
|
||||
.GetSection("Security:Jwt")
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
"WindowSeconds": 60,
|
||||
"QueueLimit": 0
|
||||
},
|
||||
"Security": {
|
||||
"Jwt": {
|
||||
"SigningKey": "development-only-tiku-signing-key-change-before-production"
|
||||
},
|
||||
"TenantSecrets": {
|
||||
"KeyId": "development-v1",
|
||||
"MasterKey": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
|
||||
}
|
||||
},
|
||||
"Storage": {
|
||||
"AliyunOss": {
|
||||
"Region": "cn-hangzhou",
|
||||
|
||||
@@ -84,10 +84,14 @@
|
||||
"Jwt": {
|
||||
"Issuer": "tiku-backend",
|
||||
"Audience": "tiku-api",
|
||||
"SigningKey": "development-only-tiku-signing-key-change-before-production",
|
||||
"SigningKey": "",
|
||||
"AccessTokenMinutes": 30,
|
||||
"RefreshTokenDays": 30,
|
||||
"ValidateSessions": true
|
||||
},
|
||||
"TenantSecrets": {
|
||||
"KeyId": "",
|
||||
"MasterKey": ""
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
|
||||
Reference in New Issue
Block a user