fix(host,security): wire static assets, DI lifetimes, form login, dev-stub LDAP
Six interlocking fixes surfaced while smoke-testing the fused Host in a browser: - Host/Program.cs: UseStaticWebAssets() opts into the RCL static-asset pipeline in any environment (auto-only in Development), MapStaticAssets().AllowAnonymous() exempts CSS/JS from the AddOtOpcUaAuth fallback policy, and AddCascadingAuthenticationState() lets <AuthorizeView/> work inside interactive components (NavSidebar's session block). - Security/ServiceCollectionExtensions: ILdapAuthService Scoped → Singleton — consumed by the Singleton LdapOpcUaUserAuthenticator on driver-role nodes. Crash only surfaced in Development (ValidateOnBuild=true). - Security/Endpoints/AuthEndpoints: /auth/login now dispatches on Content-Type — application/json keeps the original 204/401/503 contract for tests, and application/x-www-form-urlencoded (the browser <form>) gets a redirect dance. DisableAntiforgery on the login endpoint (it's the entry point, no prior session) and AllowAnonymous to override the fallback policy. - Security/Ldap/LdapOptions + LdapAuthService: real DevStubMode property; when true the auth service bypasses the LDAP bind and returns a FleetAdmin role so dev/test can navigate the full Admin UI without GLAuth running. - AdminUI/EndpointRouteBuilderExtensions: doc-comment update about static-asset flow (the actual MapStaticAssets call lives in Host/Program.cs).
This commit is contained in:
@@ -28,6 +28,11 @@ var hasDriver = roles.Contains("driver");
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Razor class library static assets (_content/<libname>/...) only auto-enable in
|
||||
// the Development environment. Opt in explicitly so the AdminUI's CSS/JS works
|
||||
// regardless of ASPNETCORE_ENVIRONMENT.
|
||||
builder.WebHost.UseStaticWebAssets();
|
||||
|
||||
// Per-role appsettings overlay: appsettings.{role}.json (single role) or appsettings.admin-driver.json
|
||||
// (both). Optional — base appsettings.json carries enough to boot if these don't exist.
|
||||
var roleSuffix = roles.Length == 0 ? null : string.Join('-', roles.OrderBy(r => r, StringComparer.Ordinal));
|
||||
@@ -111,6 +116,9 @@ if (hasAdmin)
|
||||
// Auth + AdminUI surface only mounted on admin-role nodes. Driver-only nodes have no UI.
|
||||
builder.Services.AddOtOpcUaAuth(builder.Configuration);
|
||||
builder.Services.AddAdminUI();
|
||||
// Flow AuthenticationState through cascading parameters so <AuthorizeView/> works
|
||||
// inside interactive components (NavSidebar's session block).
|
||||
builder.Services.AddCascadingAuthenticationState();
|
||||
builder.Services.AddSignalR();
|
||||
builder.Services.AddOtOpcUaAdminClients();
|
||||
}
|
||||
@@ -121,6 +129,12 @@ builder.Services.AddOtOpcUaObservability();
|
||||
var app = builder.Build();
|
||||
app.UseSerilogRequestLogging();
|
||||
|
||||
// Razor class library static assets (_content/<libname>/...) are served via endpoint
|
||||
// routing, NOT the UseStaticFiles middleware — so we MUST mark the static-asset
|
||||
// endpoints AllowAnonymous, otherwise the AddOtOpcUaAuth fallback RequireAuthenticatedUser
|
||||
// policy 401s every CSS/JS request and the login page renders unstyled.
|
||||
app.MapStaticAssets().AllowAnonymous();
|
||||
|
||||
if (hasAdmin)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
|
||||
Reference in New Issue
Block a user