fix(security): finish the bearer-token design and cache role mappings (review 2026-10-21 05/U1, 05/P1)
- ManagementAuthenticator accepts Authorization: Bearer <jwt> alongside Basic on /management, the audit REST endpoints and the debug-stream hub. Tokens are validated locally (HS256 only, alg=none rejected, issuer/audience, lifetime with 30 s skew); roles and site scope inside a valid token are authoritative for its lifetime, so a bearer call costs no LDAP bind and no role re-map. - /auth/token returns expires_in + management_bearer:true, carries username, display name, roles and permitted sites, and answers 404 under DisableLogin. - CLI exchanges credentials once per process (in-memory CliTokenStore), sends Bearer, re-exchanges once on 401 then falls back to Basic; older/login-disabled servers are Basic-only; bad credentials are not retried with Basic. Debug stream uses the token via AccessTokenProvider. SCADABRIDGE_AUTH_MODE=basic opts out. - StartupValidator fails a Central boot on a JwtSigningKey under 32 UTF-8 bytes; fixed the false 'fail-fast at construction' comment. Removed the dead RefreshToken/RecordActivity/ShouldRefresh/IsIdleTimedOut members and the inert JwtRefreshThresholdMinutes; JwtExpiryMinutes now documented as the bearer lifetime (validated > 0). - RoleMapper reads through a process-wide RoleMappingCache (RoleMappingCacheSeconds, default 30 s): one refresh loads the table plus every Deployer mapping's scope rules, Invalidate() drops it (generation-guarded against in-flight refreshes). - Component-Security.md / Component-CLI.md / CLI README describe the real model (cookie claims ticket, bearer for CLI) instead of a cookie-embedded JWT.
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.CLI.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Assembly-wide test setup. The command/contract tests drive the CLI against single-request
|
||||
/// fake servers (one accepted socket, or a stub handler that records "the" request), so they
|
||||
/// pin the CLI to HTTP Basic: with the default token mode every process's first call would be
|
||||
/// a <c>POST /auth/token</c> exchange those fakes do not model. The bearer exchange itself is
|
||||
/// covered by <see cref="ManagementHttpClientTokenTests"/>, which opts in explicitly through an
|
||||
/// isolated <see cref="CliTokenStore"/> and is unaffected by this switch.
|
||||
/// </summary>
|
||||
internal static class CliTestAssemblySetup
|
||||
{
|
||||
#pragma warning disable CA2255 // ModuleInitializer in a test assembly is intentional.
|
||||
[ModuleInitializer]
|
||||
internal static void ForceBasicAuthForContractTests()
|
||||
#pragma warning restore CA2255
|
||||
{
|
||||
Environment.SetEnvironmentVariable(ManagementHttpClient.AuthModeEnvVar, "basic");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user