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>
105 lines
5.5 KiB
Markdown
105 lines
5.5 KiB
Markdown
# OPC UA Server
|
|
|
|
The OPC UA server component hosts the Galaxy-backed namespace on a configurable TCP endpoint and exposes deployed System Platform objects and attributes to OPC UA clients.
|
|
|
|
## Configuration
|
|
|
|
`OpcUaConfiguration` defines the server endpoint and session settings. All properties have sensible defaults:
|
|
|
|
| Property | Default | Description |
|
|
|----------|---------|-------------|
|
|
| `Port` | `4840` | TCP port the server listens on |
|
|
| `EndpointPath` | `/LmxOpcUa` | URI path appended to the base address |
|
|
| `ServerName` | `LmxOpcUa` | Application name presented to clients |
|
|
| `GalaxyName` | `ZB` | Galaxy name used in the namespace URI |
|
|
| `MaxSessions` | `100` | Maximum concurrent client sessions |
|
|
| `SessionTimeoutMinutes` | `30` | Idle session timeout |
|
|
| `AlarmTrackingEnabled` | `false` | Enables `AlarmConditionState` nodes for alarm attributes |
|
|
|
|
The resulting endpoint URL is `opc.tcp://0.0.0.0:{Port}{EndpointPath}`, e.g., `opc.tcp://0.0.0.0:4840/LmxOpcUa`.
|
|
|
|
The namespace URI follows the pattern `urn:{GalaxyName}:LmxOpcUa` and serves as both the `ApplicationUri` and `ProductUri`.
|
|
|
|
## Programmatic ApplicationConfiguration
|
|
|
|
`OpcUaServerHost` builds the entire `ApplicationConfiguration` in code. There are no XML configuration files. This keeps deployment simple on factory floor machines where editing XML is error-prone.
|
|
|
|
The configuration covers:
|
|
|
|
- **ServerConfiguration** -- base address, session limits, security policies, and user token policies
|
|
- **SecurityConfiguration** -- certificate store paths under `%LOCALAPPDATA%\OPC Foundation\pki\`, auto-accept enabled
|
|
- **TransportQuotas** -- 4 MB max message/string/byte-string size, 120-second operation timeout, 1-hour security token lifetime
|
|
- **TraceConfiguration** -- OPC Foundation SDK tracing is disabled (output path `null`, trace masks `0`); all logging goes through Serilog instead
|
|
|
|
## Security Policy
|
|
|
|
The server runs with `MessageSecurityMode.None` and `SecurityPolicies.None`:
|
|
|
|
```csharp
|
|
SecurityPolicies = { new ServerSecurityPolicy
|
|
{
|
|
SecurityMode = MessageSecurityMode.None,
|
|
SecurityPolicyUri = SecurityPolicies.None
|
|
} }
|
|
```
|
|
|
|
This is intentional for plant-floor deployments where the server sits on an isolated OT network. Galaxy-level security classification controls write access per attribute rather than at the transport layer.
|
|
|
|
### User token policies
|
|
|
|
`UserTokenPolicies` are dynamically configured based on the `Authentication` settings in `appsettings.json`:
|
|
|
|
- An `Anonymous` user token policy is added when `AllowAnonymous` is `true` (the default).
|
|
- A `UserName` user token policy is added when the `Users` list contains at least one entry.
|
|
|
|
Both policies can be active simultaneously, allowing clients to connect with or without credentials.
|
|
|
|
### Session impersonation
|
|
|
|
When a client presents `UserName` credentials, the server validates them through `IUserAuthenticationProvider`. If the credentials do not match any entry in the configured `Users` list, the session is rejected.
|
|
|
|
On successful validation, the session identity is set to a `RoleBasedIdentity` that carries the user's granted role IDs. Authenticated users receive the `WellKnownRole_AuthenticatedUser` role. Anonymous connections receive the `WellKnownRole_Anonymous` role. These roles are used downstream by the write override to enforce `AnonymousCanWrite` restrictions.
|
|
|
|
## Certificate handling
|
|
|
|
On startup, `OpcUaServerHost.StartAsync` calls `CheckApplicationInstanceCertificate(false, 2048)` to locate or create a 2048-bit self-signed certificate. The certificate subject follows the format `CN={ServerName}, O=ZB MOM, DC=localhost`. Certificate stores use the directory-based store type under `%LOCALAPPDATA%\OPC Foundation\pki\`:
|
|
|
|
| Store | Path suffix |
|
|
|-------|-------------|
|
|
| Own | `pki/own` |
|
|
| Trusted issuers | `pki/issuer` |
|
|
| Trusted peers | `pki/trusted` |
|
|
| Rejected | `pki/rejected` |
|
|
|
|
`AutoAcceptUntrustedCertificates` is set to `true` so the server does not reject client certificates.
|
|
|
|
## Server class hierarchy
|
|
|
|
### LmxOpcUaServer extends StandardServer
|
|
|
|
`LmxOpcUaServer` inherits from the OPC Foundation `StandardServer` base class and overrides two methods:
|
|
|
|
- **`CreateMasterNodeManager`** -- Instantiates `LmxNodeManager` with the Galaxy namespace URI, the `IMxAccessClient` for runtime I/O, performance metrics, and an optional `HistorianDataSource`. The node manager is wrapped in a `MasterNodeManager` with no additional core node managers.
|
|
- **`LoadServerProperties`** -- Returns server metadata: manufacturer `ZB MOM`, product `LmxOpcUa Server`, and the assembly version as the software version.
|
|
|
|
### Session tracking
|
|
|
|
`LmxOpcUaServer` exposes `ActiveSessionCount` by querying `ServerInternal.SessionManager.GetSessions().Count`. `OpcUaServerHost` surfaces this for status reporting.
|
|
|
|
## Startup and Shutdown
|
|
|
|
`OpcUaServerHost.StartAsync` performs the following sequence:
|
|
|
|
1. Build `ApplicationConfiguration` programmatically
|
|
2. Validate the configuration via `appConfig.Validate(ApplicationType.Server)`
|
|
3. Create `ApplicationInstance` and check/create the application certificate
|
|
4. Instantiate `LmxOpcUaServer` and start it via `ApplicationInstance.Start`
|
|
|
|
`OpcUaServerHost.Stop` calls `_server.Stop()` and nulls both the server and application instance references. The class implements `IDisposable`, delegating to `Stop`.
|
|
|
|
## Key source files
|
|
|
|
- `src/ZB.MOM.WW.LmxOpcUa.Host/OpcUa/OpcUaServerHost.cs` -- Application lifecycle and programmatic configuration
|
|
- `src/ZB.MOM.WW.LmxOpcUa.Host/OpcUa/LmxOpcUaServer.cs` -- StandardServer subclass and node manager creation
|
|
- `src/ZB.MOM.WW.LmxOpcUa.Host/Configuration/OpcUaConfiguration.cs` -- Configuration POCO
|