diff --git a/src/ZB.MOM.WW.ScadaBridge.Security/Auth/AuthDisableLoginOptions.cs b/src/ZB.MOM.WW.ScadaBridge.Security/Auth/AuthDisableLoginOptions.cs index ff8b1606..ba7d9fa8 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Security/Auth/AuthDisableLoginOptions.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Security/Auth/AuthDisableLoginOptions.cs @@ -8,7 +8,15 @@ namespace ZB.MOM.WW.ScadaBridge.Security.Auth; /// public sealed class AuthDisableLoginOptions { - /// Configuration section name (ScadaBridge:Security:Auth). + /// + /// Configuration section name (ScadaBridge:Security:Auth). + /// This is a CHILD sub-section of ScadaBridge:Security (where + /// binds the parent fields) — not a sibling. + /// In appsettings.json nest it under the existing Security object: + /// + /// "ScadaBridge": { "Security": { "Auth": { "DisableLogin": true } } } + /// + /// public const string SectionName = "ScadaBridge:Security:Auth"; /// When true, disable login and auto-authenticate every request. Default false. diff --git a/src/ZB.MOM.WW.ScadaBridge.Security/ServiceCollectionExtensions.cs b/src/ZB.MOM.WW.ScadaBridge.Security/ServiceCollectionExtensions.cs index f9c3022b..94edacac 100644 --- a/src/ZB.MOM.WW.ScadaBridge.Security/ServiceCollectionExtensions.cs +++ b/src/ZB.MOM.WW.ScadaBridge.Security/ServiceCollectionExtensions.cs @@ -127,7 +127,7 @@ public static class ServiceCollectionExtensions "AUTH DISABLED (ScadaBridge:Security:Auth:DisableLogin=true) — every request is " + "authenticated as '{User}' with FULL permissions ({Roles}) across ALL sites. This " + "is a SCADA control surface; dev/test ONLY — never enable in production.", - opts.User, string.Join(",", Roles.All))); + opts.User, string.Join(", ", Roles.All))); } else { diff --git a/tests/ZB.MOM.WW.ScadaBridge.Security.Tests/DisableLoginRegistrationTests.cs b/tests/ZB.MOM.WW.ScadaBridge.Security.Tests/DisableLoginRegistrationTests.cs index c84fb094..c4075ba3 100644 --- a/tests/ZB.MOM.WW.ScadaBridge.Security.Tests/DisableLoginRegistrationTests.cs +++ b/tests/ZB.MOM.WW.ScadaBridge.Security.Tests/DisableLoginRegistrationTests.cs @@ -32,4 +32,30 @@ public class DisableLoginRegistrationTests var scheme = await ResolveCookieSchemeAsync(disableLogin: false); Assert.Equal(typeof(CookieAuthenticationHandler), scheme!.HandlerType); } + + /// + /// When disableLogin: false (the production path) the M2.19 idle-timeout / + /// role-refresh hook MUST be wired on the cookie scheme's + /// . + /// This pin-test ensures a future refactor cannot silently drop the hook without + /// a red test. + /// + [Fact] + public async Task FlagFalse_CookieScheme_OnValidatePrincipalIsWired() + { + var services = new ServiceCollection(); + services.AddLogging(); + // Provide default SecurityOptions so the PostConfigure that reads + // IOptions (cookie-hardening + name) can resolve successfully. + services.Configure(_ => { }); + services.AddSecurity(disableLogin: false); + + await using var sp = services.BuildServiceProvider(); + + var options = sp + .GetRequiredService>() + .Get(CookieAuthenticationDefaults.AuthenticationScheme); + + Assert.NotNull(options.Events?.OnValidatePrincipal); + } }