fix(adminui): capture audit username at click time, not at panel init
v2-ci / build (push) Failing after 48s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
v2-ci / build (push) Failing after 48s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
DriverStatusPanel previously cached the username in a field at OnInitializedAsync and forwarded the cached value into RestartDriver / ReconnectDriver messages. A token refresh or claim change mid- circuit would land the stale name in the audit ConfigEdit row. Re-reads AuthenticationStateProvider at button-click time so the audit entry reflects the current principal.
This commit is contained in:
+20
-4
@@ -149,7 +149,6 @@
|
||||
|
||||
// Authorization
|
||||
private bool _canOperate;
|
||||
private string? _currentUserName;
|
||||
|
||||
// Action state
|
||||
private bool _busyReconnect;
|
||||
@@ -162,8 +161,9 @@
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// Check DriverOperator authorization so buttons only render for permitted users.
|
||||
// The username for audit logging is re-read at button-click time (not captured here)
|
||||
// so token-refreshes mid-session land in audit entries accurately.
|
||||
var auth = await AuthState.GetAuthenticationStateAsync();
|
||||
_currentUserName = auth.User.Identity?.Name ?? auth.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value ?? "unknown";
|
||||
var authResult = await AuthorizationService.AuthorizeAsync(auth.User, null, "DriverOperator");
|
||||
_canOperate = authResult.Succeeded;
|
||||
|
||||
@@ -213,8 +213,9 @@
|
||||
StateHasChanged();
|
||||
try
|
||||
{
|
||||
var userName = await GetCurrentUserNameAsync();
|
||||
var result = await AdminOps.AskAsync<ReconnectDriverResult>(
|
||||
new ReconnectDriver(ClusterId, DriverInstanceId, _currentUserName ?? "unknown", Guid.NewGuid()),
|
||||
new ReconnectDriver(ClusterId, DriverInstanceId, userName, Guid.NewGuid()),
|
||||
new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(15)).Token);
|
||||
ShowOpResult(result.Ok, result.Ok ? "Reconnect dispatched" : (result.Message ?? "Failed"));
|
||||
}
|
||||
@@ -237,8 +238,9 @@
|
||||
StateHasChanged();
|
||||
try
|
||||
{
|
||||
var userName = await GetCurrentUserNameAsync();
|
||||
var result = await AdminOps.AskAsync<RestartDriverResult>(
|
||||
new RestartDriver(ClusterId, DriverInstanceId, _currentUserName ?? "unknown", Guid.NewGuid()),
|
||||
new RestartDriver(ClusterId, DriverInstanceId, userName, Guid.NewGuid()),
|
||||
new System.Threading.CancellationTokenSource(TimeSpan.FromSeconds(15)).Token);
|
||||
ShowOpResult(result.Ok, result.Ok ? "Restart dispatched" : (result.Message ?? "Failed"));
|
||||
}
|
||||
@@ -253,6 +255,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-reads the AuthenticationState at call time so the username forwarded to the
|
||||
/// audit log reflects the current claims-principal — survives token refresh / role
|
||||
/// change during a long-lived Blazor circuit. Returns "unknown" if no Name claim is
|
||||
/// present (auth requirements upstream should normally prevent this).
|
||||
/// </summary>
|
||||
private async Task<string> GetCurrentUserNameAsync()
|
||||
{
|
||||
var auth = await AuthState.GetAuthenticationStateAsync();
|
||||
return auth.User.Identity?.Name
|
||||
?? auth.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value
|
||||
?? "unknown";
|
||||
}
|
||||
|
||||
private void ShowOpResult(bool ok, string message)
|
||||
{
|
||||
_opResultOk = ok;
|
||||
|
||||
Reference in New Issue
Block a user