117 lines
4.4 KiB
C#
117 lines
4.4 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|
using Microsoft.Extensions.Options;
|
|
using StellaOps.Auth.Abstractions;
|
|
using StellaOps.Auth.ServerIntegration;
|
|
using StellaOps.Auth.ServerIntegration.Tenancy;
|
|
using StellaOps.Scanner.Cartographer.Options;
|
|
|
|
using StellaOps.Router.AspNet;
|
|
var builder = WebApplication.CreateBuilder(args);
|
|
|
|
builder.Configuration
|
|
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
|
|
.AddEnvironmentVariables("CARTOGRAPHER_");
|
|
|
|
builder.Services.AddOptions();
|
|
builder.Services.AddLogging();
|
|
|
|
var authoritySection = builder.Configuration.GetSection("Cartographer:Authority");
|
|
builder.Services.AddOptions<CartographerAuthorityOptions>()
|
|
.Bind(authoritySection)
|
|
.PostConfigure(CartographerAuthorityOptionsConfigurator.ApplyDefaults)
|
|
.ValidateOnStart();
|
|
builder.Services.AddSingleton<IValidateOptions<CartographerAuthorityOptions>, CartographerAuthorityOptionsValidator>();
|
|
|
|
var authorityOptions = authoritySection.Get<CartographerAuthorityOptions>() ?? new CartographerAuthorityOptions();
|
|
CartographerAuthorityOptionsConfigurator.ApplyDefaults(authorityOptions);
|
|
authorityOptions.Validate();
|
|
|
|
if (authorityOptions.Enabled)
|
|
{
|
|
builder.Services.AddStellaOpsResourceServerAuthentication(
|
|
builder.Configuration,
|
|
configurationSection: null,
|
|
configure: resourceOptions =>
|
|
{
|
|
resourceOptions.Authority = authorityOptions.Issuer;
|
|
resourceOptions.RequireHttpsMetadata = authorityOptions.RequireHttpsMetadata;
|
|
resourceOptions.MetadataAddress = authorityOptions.MetadataAddress;
|
|
resourceOptions.BackchannelTimeout = TimeSpan.FromSeconds(authorityOptions.BackchannelTimeoutSeconds);
|
|
resourceOptions.TokenClockSkew = TimeSpan.FromSeconds(authorityOptions.TokenClockSkewSeconds);
|
|
|
|
resourceOptions.Audiences.Clear();
|
|
foreach (var audience in authorityOptions.Audiences)
|
|
{
|
|
resourceOptions.Audiences.Add(audience);
|
|
}
|
|
|
|
resourceOptions.RequiredScopes.Clear();
|
|
foreach (var scope in authorityOptions.RequiredScopes)
|
|
{
|
|
resourceOptions.RequiredScopes.Add(scope);
|
|
}
|
|
});
|
|
|
|
builder.Services.AddAuthorization(options =>
|
|
{
|
|
if (authorityOptions.AllowAnonymousFallback)
|
|
{
|
|
return;
|
|
}
|
|
|
|
options.FallbackPolicy = new AuthorizationPolicyBuilder()
|
|
.RequireAuthenticatedUser()
|
|
.AddAuthenticationSchemes(StellaOpsAuthenticationDefaults.AuthenticationScheme)
|
|
.AddRequirements(new StellaOpsScopeRequirement(authorityOptions.RequiredScopes.ToArray()))
|
|
.Build();
|
|
});
|
|
}
|
|
|
|
// TODO: register Cartographer graph builders, overlay workers, and Authority client once implementations land.
|
|
builder.Services.AddHealthChecks()
|
|
.AddCheck("cartographer_ready", () => HealthCheckResult.Healthy(), tags: new[] { "ready" });
|
|
|
|
builder.Services.AddStellaOpsTenantServices();
|
|
builder.Services.AddStellaOpsCors(builder.Environment, builder.Configuration);
|
|
|
|
// Stella Router integration
|
|
var routerEnabled = builder.Services.AddRouterMicroservice(
|
|
builder.Configuration,
|
|
serviceName: "cartographer",
|
|
version: System.Reflection.CustomAttributeExtensions.GetCustomAttribute<System.Reflection.AssemblyInformationalVersionAttribute>(System.Reflection.Assembly.GetExecutingAssembly())?.InformationalVersion ?? "1.0.0",
|
|
routerOptionsSection: "Router");
|
|
builder.TryAddStellaOpsLocalBinding("cartographer");
|
|
var app = builder.Build();
|
|
app.LogStellaOpsLocalHostname("cartographer");
|
|
|
|
if (!authorityOptions.Enabled)
|
|
{
|
|
app.Logger.LogWarning("Cartographer Authority authentication is disabled; enable it before production deployments.");
|
|
}
|
|
else if (authorityOptions.AllowAnonymousFallback)
|
|
{
|
|
app.Logger.LogWarning("Cartographer Authority allows anonymous fallback; disable fallback before production rollout.");
|
|
}
|
|
|
|
app.UseStellaOpsCors();
|
|
if (authorityOptions.Enabled)
|
|
{
|
|
app.UseAuthentication();
|
|
app.UseAuthorization();
|
|
app.TryUseStellaRouter(routerEnabled);
|
|
}
|
|
app.UseStellaOpsTenantMiddleware();
|
|
|
|
app.MapHealthChecks("/healthz").AllowAnonymous();
|
|
app.MapHealthChecks("/readyz", new Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions
|
|
{
|
|
Predicate = check => check.Tags.Contains("ready")
|
|
}).AllowAnonymous();
|
|
|
|
app.TryRefreshStellaRouterEndpoints(routerEnabled);
|
|
app.Run();
|
|
|
|
public partial class Program;
|
|
|