Add authentication and role-based write access control
Implements configurable user authentication (anonymous + username/password) with pluggable credential provider (IUserAuthenticationProvider). Anonymous writes can be disabled via AnonymousCanWrite setting while reads remain open. Adds -U/-P flags to all CLI commands for authenticated sessions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,8 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
private readonly IMxAccessClient _mxAccessClient;
|
||||
private readonly PerformanceMetrics _metrics;
|
||||
private readonly HistorianDataSource? _historianDataSource;
|
||||
private readonly AuthenticationConfiguration _authConfig;
|
||||
private readonly IUserAuthenticationProvider? _authProvider;
|
||||
private ApplicationInstance? _application;
|
||||
private LmxOpcUaServer? _server;
|
||||
|
||||
@@ -48,12 +50,16 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
/// <param name="metrics">The metrics collector shared with the node manager and runtime bridge.</param>
|
||||
/// <param name="historianDataSource">The optional historian adapter that enables OPC UA history read support.</param>
|
||||
public OpcUaServerHost(OpcUaConfiguration config, IMxAccessClient mxAccessClient, PerformanceMetrics metrics,
|
||||
HistorianDataSource? historianDataSource = null)
|
||||
HistorianDataSource? historianDataSource = null,
|
||||
AuthenticationConfiguration? authConfig = null,
|
||||
IUserAuthenticationProvider? authProvider = null)
|
||||
{
|
||||
_config = config;
|
||||
_mxAccessClient = mxAccessClient;
|
||||
_metrics = metrics;
|
||||
_historianDataSource = historianDataSource;
|
||||
_authConfig = authConfig ?? new AuthenticationConfiguration();
|
||||
_authProvider = authProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -84,10 +90,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
SecurityPolicyUri = SecurityPolicies.None
|
||||
}
|
||||
},
|
||||
UserTokenPolicies =
|
||||
{
|
||||
new UserTokenPolicy(UserTokenType.Anonymous)
|
||||
}
|
||||
UserTokenPolicies = BuildUserTokenPolicies()
|
||||
},
|
||||
|
||||
SecurityConfiguration = new SecurityConfiguration
|
||||
@@ -160,7 +163,8 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
certOk = await _application.CheckApplicationInstanceCertificate(false, 2048);
|
||||
}
|
||||
|
||||
_server = new LmxOpcUaServer(_config.GalaxyName, _mxAccessClient, _metrics, _historianDataSource, _config.AlarmTrackingEnabled);
|
||||
_server = new LmxOpcUaServer(_config.GalaxyName, _mxAccessClient, _metrics, _historianDataSource,
|
||||
_config.AlarmTrackingEnabled, _authConfig, _authProvider);
|
||||
await _application.Start(_server);
|
||||
|
||||
Log.Information("OPC UA server started on opc.tcp://localhost:{Port}{EndpointPath} (namespace={Namespace})",
|
||||
@@ -188,6 +192,23 @@ namespace ZB.MOM.WW.LmxOpcUa.Host.OpcUa
|
||||
}
|
||||
}
|
||||
|
||||
private UserTokenPolicyCollection BuildUserTokenPolicies()
|
||||
{
|
||||
var policies = new UserTokenPolicyCollection();
|
||||
if (_authConfig.AllowAnonymous)
|
||||
policies.Add(new UserTokenPolicy(UserTokenType.Anonymous));
|
||||
if (_authConfig.Users.Count > 0)
|
||||
policies.Add(new UserTokenPolicy(UserTokenType.UserName));
|
||||
|
||||
if (policies.Count == 0)
|
||||
{
|
||||
Log.Warning("No authentication methods configured — adding Anonymous as fallback");
|
||||
policies.Add(new UserTokenPolicy(UserTokenType.Anonymous));
|
||||
}
|
||||
|
||||
return policies;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stops the host and releases server resources.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user