4.4 KiB
Authentication and customer authorization
Boundary
The platform owns authorization even when authentication is delegated later. An upstream identity system may prove who the user is, but it cannot bypass the local menu and vehicle Scope checks.
Current providers:
local: username/password login and opaque server session.legacy-token: existing static operational Bearer tokens, retained for emergency access and migration.disabled: local development only.
The API exposes IdentityAdapter as the future signed-token or introspection boundary. Yudao Cloud / RuoYi Sys integration must validate a short-lived signed credential and map (auth_provider, external_subject) to platform_user. Never trust unsigned identity headers from a reverse proxy.
Roles and menus
adminreceives all platform menus and can manage customer accounts.customerreceives only explicitly granted menu keys from the fixed customer catalog:monitor,vehicles,tracks,statistics.- The server rejects every unspecified customer API route. The web navigation and route guard are usability layers, not the authorization boundary.
Shared vehicle APIs used by more than one customer menu are allowed when the account owns any relevant menu, but every data query still receives the same VIN Scope.
Vehicle Scope
platform_user_vehicle is the authoritative local grant table. Customer principals carry a bounded list of active VIN grants. Service queries inject it as scopeVins before SQL construction, and the MySQL builders apply the list to vehicle, realtime, monitor, track resolution and mileage queries.
Explicit VINs outside the grant set return 403 VEHICLE_PERMISSION_DENIED. A missing vehicle grant is fail-closed and produces an empty collection. Plate-number resolution is performed inside the same VIN Scope.
Sessions and password policy
- Passwords are stored with bcrypt cost 12.
- Password length is 10-128 characters and must contain at least three of: lowercase, uppercase, number, symbol.
- Five consecutive failures lock the account for 15 minutes.
- Login creates a cryptographically random opaque token; only SHA-256 is stored in MySQL.
- Default session lifetime is 12 hours (
AUTH_SESSION_TTL_HOURS). - The browser stores the token in
sessionStorage, not persistent storage. - Disabling an account or resetting its password revokes all active sessions immediately.
- Successful/failed logins and account permission changes are written to
platform_auth_audit.
Session principals are cached in the API for at most 30 seconds to keep realtime polling inexpensive. Account disable and password reset revoke the database session immediately; permission updates invalidate local cache entries and become visible across multiple API instances within the cache window.
Bootstrap
The first local administrator is created only when no administrator exists:
BOOTSTRAP_ADMIN_USERNAME=admin
BOOTSTRAP_ADMIN_PASSWORD=<strong one-time bootstrap secret>
AUTH_SESSION_TTL_HOURS=12
The bootstrap password does not overwrite an existing administrator. Keep the environment file root-owned and mode 0600. After an administrator changes credentials through the account password dialog, remove the bootstrap password from the environment.
APIs
POST /api/v2/auth/login
POST /api/v2/auth/logout
PUT /api/v2/auth/password
GET /api/v2/session
GET /api/v2/admin/users
POST /api/v2/admin/users
PUT /api/v2/admin/users/{id}
Customer creation/update accepts display name, optional external customer/tenant references, account status, menu keys and VINs. Username is immutable after creation. Password reset and account disable invalidate previous sessions.
External identity migration
- Add a concrete
IdentityAdapterfor the upstream issuer using JWKS signature validation or server-side token introspection. - Match the validated issuer subject to
platform_user.auth_providerandplatform_user.external_subject. - Keep menu and VIN grants in the platform initially, or sync them into the same local projection with source/version metadata.
- Run local and external providers in parallel during migration; do not remove the operational token until external login and rollback are proven.
- Preserve
subjectId,customerRef,tenantRef,menuKeys,vehicleCountandauthProviderin the session contract so the web application does not depend on a Yudao/RuoYi-specific payload.