Add LDAP authentication with role-based OPC UA permissions
Replace static user list with GLAuth LDAP authentication. Group membership (ReadOnly, ReadWrite, AlarmAck) maps to granular OPC UA permissions for write and alarm-ack operations. Anonymous can still browse and read but not write. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -116,11 +116,62 @@ Controls user authentication and write authorization for the OPC UA server. Defi
|
||||
| `AnonymousCanWrite` | `bool` | `true` | Permits anonymous users to write when `true` |
|
||||
| `Users` | `List<UserCredential>` | `[]` | List of username/password credentials for `UserName` token authentication |
|
||||
|
||||
Each entry in the `Users` list has two properties: `Username` (string) and `Password` (string).
|
||||
Each entry in the `Users` list has two properties: `Username` (string) and `Password` (string). The `Users` list is ignored when `Ldap.Enabled` is `true`.
|
||||
|
||||
The defaults preserve the existing behavior: anonymous clients can connect, read, and write with no credentials required. To restrict writes to authenticated users, set `AnonymousCanWrite` to `false` and add entries to the `Users` list.
|
||||
#### LDAP Authentication
|
||||
|
||||
Example configuration:
|
||||
When `Ldap.Enabled` is `true`, credentials are validated against the configured LDAP server and group membership determines OPC UA permissions. The `Users` list is ignored.
|
||||
|
||||
| Property | Type | Default | Description |
|
||||
|----------|------|---------|-------------|
|
||||
| `Ldap.Enabled` | `bool` | `false` | Enables LDAP authentication |
|
||||
| `Ldap.Host` | `string` | `localhost` | LDAP server hostname |
|
||||
| `Ldap.Port` | `int` | `3893` | LDAP server port |
|
||||
| `Ldap.BaseDN` | `string` | `dc=lmxopcua,dc=local` | Base DN for LDAP operations |
|
||||
| `Ldap.BindDnTemplate` | `string` | `cn={username},dc=lmxopcua,dc=local` | Bind DN template (`{username}` is replaced) |
|
||||
| `Ldap.ServiceAccountDn` | `string` | `""` | Service account DN for group lookups |
|
||||
| `Ldap.ServiceAccountPassword` | `string` | `""` | Service account password |
|
||||
| `Ldap.TimeoutSeconds` | `int` | `5` | Connection timeout |
|
||||
| `Ldap.ReadOnlyGroup` | `string` | `ReadOnly` | LDAP group granting read-only access |
|
||||
| `Ldap.ReadWriteGroup` | `string` | `ReadWrite` | LDAP group granting read-write access |
|
||||
| `Ldap.AlarmAckGroup` | `string` | `AlarmAck` | LDAP group granting alarm acknowledgment |
|
||||
|
||||
#### Permission Model
|
||||
|
||||
When LDAP is enabled, authenticated users receive permissions based on their LDAP group membership:
|
||||
|
||||
| LDAP Group | Permission |
|
||||
|---|---|
|
||||
| ReadOnly | Browse and read nodes |
|
||||
| ReadWrite | Browse, read, and write tag values |
|
||||
| AlarmAck | Acknowledge alarms |
|
||||
|
||||
Users can belong to multiple groups. The `admin` user in the default GLAuth configuration belongs to all three groups.
|
||||
|
||||
Example with LDAP authentication:
|
||||
|
||||
```json
|
||||
"Authentication": {
|
||||
"AllowAnonymous": true,
|
||||
"AnonymousCanWrite": false,
|
||||
"Users": [],
|
||||
"Ldap": {
|
||||
"Enabled": true,
|
||||
"Host": "localhost",
|
||||
"Port": 3893,
|
||||
"BaseDN": "dc=lmxopcua,dc=local",
|
||||
"BindDnTemplate": "cn={username},dc=lmxopcua,dc=local",
|
||||
"ServiceAccountDn": "cn=serviceaccount,dc=lmxopcua,dc=local",
|
||||
"ServiceAccountPassword": "serviceaccount123",
|
||||
"TimeoutSeconds": 5,
|
||||
"ReadOnlyGroup": "ReadOnly",
|
||||
"ReadWriteGroup": "ReadWrite",
|
||||
"AlarmAckGroup": "AlarmAck"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Example with static user list (no LDAP):
|
||||
|
||||
```json
|
||||
"Authentication": {
|
||||
|
||||
@@ -257,3 +257,41 @@ The CLI tool auto-generates its own client certificate on first use (stored unde
|
||||
**Resolution:**
|
||||
- Regenerate the client certificate using SHA-256 or stronger (recommended).
|
||||
- Alternatively, set `RejectSHA1Certificates` to `false` in the server configuration (not recommended for production).
|
||||
|
||||
---
|
||||
|
||||
## LDAP Authentication
|
||||
|
||||
The server supports LDAP-based user authentication via GLAuth (or any standard LDAP server). When enabled, OPC UA `UserName` token credentials are validated by LDAP bind, and LDAP group membership controls what operations each user can perform.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
OPC UA Client → UserName Token → LmxOpcUa Server → LDAP Bind (validate credentials)
|
||||
→ LDAP Search (resolve group membership)
|
||||
→ Role assignment → Permission enforcement
|
||||
```
|
||||
|
||||
### LDAP Groups and OPC UA Permissions
|
||||
|
||||
| LDAP Group | OPC UA Permission |
|
||||
|---|---|
|
||||
| ReadOnly | Browse and read nodes |
|
||||
| ReadWrite | Read and write tag values |
|
||||
| AlarmAck | Acknowledge alarms |
|
||||
|
||||
Users can belong to multiple groups. A user with all three groups has full access.
|
||||
|
||||
### GLAuth Setup
|
||||
|
||||
The project uses [GLAuth](https://github.com/glauth/glauth) v2.4.0 as the LDAP server, installed at `C:\publish\glauth\`. See `C:\publish\glauth\auth.md` for the complete user/group reference and service management commands.
|
||||
|
||||
### Configuration
|
||||
|
||||
Enable LDAP in `appsettings.json` under `Authentication.Ldap`. See [Configuration Guide](Configuration.md) for the full property reference.
|
||||
|
||||
### Security Considerations
|
||||
|
||||
- LDAP credentials are transmitted in plaintext over the OPC UA channel unless transport security is enabled. Use `Basic256Sha256-SignAndEncrypt` for production deployments.
|
||||
- The GLAuth LDAP server itself listens on plain LDAP (port 3893). Enable LDAPS in `glauth.cfg` for environments where LDAP traffic crosses network boundaries.
|
||||
- The service account password is stored in `appsettings.json`. Protect this file with appropriate filesystem permissions.
|
||||
|
||||
Reference in New Issue
Block a user