fix(secrets): honor env-supplied LDAP bind password in live LDAP integration suite; clarify pre-host migration
This commit is contained in:
@@ -236,10 +236,19 @@ LDAP groups resolve to the `Admin` role succeeds and emits the role claim;
|
|||||||
the password into `FailureMessage`; an unknown username fails authentication; and
|
the password into `FailureMessage`; an unknown username fails authentication; and
|
||||||
an unreachable LDAP server is absorbed into a failed result rather than throwing.
|
an unreachable LDAP server is absorbed into a failed result rather than throwing.
|
||||||
|
|
||||||
|
`appsettings.json` now ships the LDAP bind password as the unexpanded
|
||||||
|
`${secret:ldap/mxgateway/bind}` token (resolved at gateway startup by the
|
||||||
|
pre-host secrets expander, which this suite's bare `ConfigurationBuilder`
|
||||||
|
does not run). Before running the live LDAP suite, set
|
||||||
|
`MxGateway__Ldap__ServiceAccountPassword` to the real GLAuth service-account
|
||||||
|
password (dev value `serviceaccount123` for the shared GLAuth) so the suite
|
||||||
|
binds with the real password instead of the literal token.
|
||||||
|
|
||||||
Run the LDAP live tests explicitly:
|
Run the LDAP live tests explicitly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$env:MXGATEWAY_RUN_LIVE_LDAP_TESTS = "1"
|
$env:MXGATEWAY_RUN_LIVE_LDAP_TESTS = "1"
|
||||||
|
$env:MxGateway__Ldap__ServiceAccountPassword = "serviceaccount123"
|
||||||
dotnet test src/ZB.MOM.WW.MxGateway.IntegrationTests/ZB.MOM.WW.MxGateway.IntegrationTests.csproj --filter FullyQualifiedName~DashboardLdapLiveTests
|
dotnet test src/ZB.MOM.WW.MxGateway.IntegrationTests/ZB.MOM.WW.MxGateway.IntegrationTests.csproj --filter FullyQualifiedName~DashboardLdapLiveTests
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -161,12 +161,32 @@ public sealed class DashboardLdapLiveTests
|
|||||||
|
|
||||||
IConfiguration configuration = new ConfigurationBuilder()
|
IConfiguration configuration = new ConfigurationBuilder()
|
||||||
.AddJsonFile(appSettingsPath, optional: false)
|
.AddJsonFile(appSettingsPath, optional: false)
|
||||||
|
.AddEnvironmentVariables()
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
// Same section production binds in AddZbLdapAuth(configuration, "MxGateway:Ldap").
|
// Same section production binds in AddZbLdapAuth(configuration, "MxGateway:Ldap").
|
||||||
// Get<T> returns null only when the section is absent; appsettings.json always
|
// Get<T> returns null only when the section is absent; appsettings.json always
|
||||||
// carries it, so fall back to shared defaults defensively rather than throw.
|
// carries it, so fall back to shared defaults defensively rather than throw.
|
||||||
return configuration.GetSection("MxGateway:Ldap").Get<LibraryLdapOptions>()
|
LibraryLdapOptions options = configuration.GetSection("MxGateway:Ldap").Get<LibraryLdapOptions>()
|
||||||
?? new LibraryLdapOptions();
|
?? new LibraryLdapOptions();
|
||||||
|
|
||||||
|
// appsettings.json now ships the bind password as the unexpanded
|
||||||
|
// "${secret:ldap/mxgateway/bind}" token (resolved at gateway startup by the
|
||||||
|
// pre-host secrets expander, which this bare ConfigurationBuilder does not run).
|
||||||
|
// AddEnvironmentVariables() above lets MxGateway__Ldap__ServiceAccountPassword
|
||||||
|
// override the token with the real password. Fail loud rather than silently
|
||||||
|
// binding with the literal token string, which would make every live test in
|
||||||
|
// this file fail with a confusing LDAP bind error instead of an actionable one.
|
||||||
|
if (string.IsNullOrEmpty(options.ServiceAccountPassword)
|
||||||
|
|| options.ServiceAccountPassword.StartsWith("${secret:", StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(
|
||||||
|
"Live LDAP tests require the real bind password via the "
|
||||||
|
+ "MxGateway__Ldap__ServiceAccountPassword environment variable "
|
||||||
|
+ "(appsettings now ships a ${secret:} token that this suite does not expand). "
|
||||||
|
+ "Set it before running.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,6 +82,9 @@ public static class GatewayApplication
|
|||||||
.BuildServiceProvider())
|
.BuildServiceProvider())
|
||||||
#pragma warning restore ASP0000
|
#pragma warning restore ASP0000
|
||||||
{
|
{
|
||||||
|
// Intentionally unconditional: the pre-host expander below needs the secrets
|
||||||
|
// store schema to exist before the first ${secret:} resolve. Secrets:RunMigrationsOnStartup
|
||||||
|
// governs only the runtime SecretsMigrationHostedService, not this bootstrap path.
|
||||||
secretsProvider.GetRequiredService<SqliteSecretsStoreMigrator>()
|
secretsProvider.GetRequiredService<SqliteSecretsStoreMigrator>()
|
||||||
.MigrateAsync(default).GetAwaiter().GetResult();
|
.MigrateAsync(default).GetAwaiter().GetResult();
|
||||||
var resolver = secretsProvider.GetRequiredService<ISecretResolver>();
|
var resolver = secretsProvider.GetRequiredService<ISecretResolver>();
|
||||||
|
|||||||
Reference in New Issue
Block a user