feat: add JoeAppEngine OPC UA nodes, fix DCL auto-reconnect and quality push
- Add JoeAppEngine folder to OPC UA nodes.json (BTCS, AlarmCntsBySeverity, Scheduler/ScanTime) - Fix DataConnectionActor: capture Self in PreStart for use from non-actor threads, preventing Self.Tell failure in Disconnected event handler - Implement InstanceActor.HandleConnectionQualityChanged to mark attributes Bad on disconnect - Fix LmxFakeProxy TagMapper to serialize arrays as JSON instead of "System.Int32[]" - Allow DataType and DataSourceReference updates in TemplateService.UpdateAttributeAsync - Update test_infra_opcua.md with JoeAppEngine documentation
This commit is contained in:
@@ -24,17 +24,21 @@ Central cluster. Sites do not have user-facing interfaces and do not perform ind
|
||||
|
||||
## Session Management
|
||||
|
||||
### JWT Tokens
|
||||
### Cookie + JWT Hybrid
|
||||
- On successful authentication, the app issues a **JWT** signed with a shared symmetric key (HMAC-SHA256). Both central cluster nodes use the same signing key from configuration, so either node can issue and validate tokens.
|
||||
- **JWT claims**: User display name, username, list of roles (Admin, Design, Deployment), and for site-scoped Deployment, the list of permitted site IDs. All authorization decisions are made from token claims without hitting the database.
|
||||
- The JWT is embedded in an **authentication cookie** rather than being passed as a bearer token. This is the correct transport for Blazor Server, where persistent SignalR circuits do not carry Authorization headers — the browser automatically sends the cookie with every SignalR connection and HTTP request.
|
||||
- The cookie is **HttpOnly** and **Secure** (requires HTTPS).
|
||||
- On each request, the server extracts and validates the JWT from the cookie. All authorization decisions are made from the JWT claims without hitting the database.
|
||||
- **JWT claims**: User display name, username, list of roles (Admin, Design, Deployment), and for site-scoped Deployment, the list of permitted site IDs.
|
||||
|
||||
### Token Lifecycle
|
||||
- **JWT expiry**: 15 minutes. On each request, if the token is near expiry, the app re-queries LDAP for current group memberships and issues a fresh token with updated claims. Roles are never more than 15 minutes stale.
|
||||
- **JWT expiry**: 15 minutes. On each request, if the cookie-embedded JWT is near expiry, the app re-queries LDAP for current group memberships and issues a fresh JWT, writing an updated cookie. Roles are never more than 15 minutes stale.
|
||||
- **Idle timeout**: Configurable, default **30 minutes**. If no requests are made within the idle window, the token is not refreshed and the user must re-login. Tracked via a last-activity timestamp in the token.
|
||||
- **Sliding refresh**: Active users stay logged in indefinitely — the token refreshes every 15 minutes as long as requests are made within the 30-minute idle window.
|
||||
|
||||
### Load Balancer Compatibility
|
||||
- JWT tokens are self-contained — no server-side session state. A load balancer in front of the central cluster can route requests to either node without sticky sessions or a shared session store. Central failover is transparent to users with valid tokens.
|
||||
- The authentication cookie carries a self-contained JWT — no server-side session state. A load balancer in front of the central cluster can route requests to either node without sticky sessions or a shared session store.
|
||||
- Since both central nodes share the same JWT signing key, either node can validate the cookie-embedded JWT. Central failover is transparent to users with valid cookies.
|
||||
|
||||
## LDAP Connection Failure
|
||||
|
||||
|
||||
Reference in New Issue
Block a user