Repository navigation
“Disable password sign-in” is not enforced on the RustDesk client API (POST /api/login) #102
Description
What happened
Setup
SSO via OIDC (Keycloak), configured and working for the console and for the RustDesk client (“Continue with SSO”).
Settings → SSO: new user policy = deny, Disable password sign-in = on.
Server access mode = approved devices only.
Users were imported with cortendesk:import-lejianwen, so they keep their original bcrypt password hashes.
Steps to reproduce
Enable SSO and turn on Disable password sign-in.
Have a user whose account still has a valid password (e.g. imported from lejianwen, or created before SSO was enabled).
In the RustDesk desktop client (API server = console URL), sign in with that username and password instead of “Continue with SSO”, or call directly:
curl -X POST https:///api/login -H 'Content-Type: application/json' -d '{"username":"","password":"","id":"test","uuid":"test"}'
Expected
The client API refuses password sign-in when “Disable password sign-in” is on (and SSO is enabled and configured), the same way the console login form does. Only the OIDC flow (/api/oidc/auth) should work.
Actual
/api/login returns an access token. The client is signed in with a password, bypassing SSO and the IdP’s MFA. The setting hides only the console form.
Cause (from reading the code)
App\Http\Controllers\Api\ClientAuthController::login() checks only is_active and Hash::check(). It never reads the password-sign-in setting. loginOptions() adds the OIDC option but does not drop password login.
With SSO-only enforced at the IdP (MFA), a password still accepted by the client API is a way around MFA. This applies especially to imported accounts, whose old passwords keep working unnoticed.
In login(), refuse password authentication with a clear error (e.g. {"error":"Password sign-in is disabled, use SSO"}) when SSO is enabled and configured and “Disable password sign-in” is on, mirroring the console behaviour. This should include the same automatic fallback when the provider is unconfigured, or CORTENDESK_OIDC_DISABLED=true. Optionally the importer could offer to drop password hashes for SSO-only installs.
Workaround in use
Reverse proxy rule returning an error for POST /api/login, so only /api/oidc/* reaches the app.
CortenDesk version
1.13.1
How CortenDesk is installed
Docker image (docker run or Compose)
Database
MySQL
ID server and relay (hbbs/hbbr)
Bundled in the CortenDesk image (default since 1.5)
RustDesk client version and platform
No response
Browser (web client issues only)
No response
Logs
Also attached
- Diagnostics export (Diagnostics → Export, a JSON file with the state of every component)
- Screenshots
- Settings → Server values (ID server, relay, API server as the clients see them, key redacted)
Anything else
No response
Activity
marcpope commentedon Oct 15, 2026
Fixed in 1.14.0. With SSO enabled and configured and Disable password sign-in on,
POST /api/loginnow refuses a password withPassword sign-in is disabled. Use single sign-on.The fallback is the console's: SSO switched off, left incomplete, orCORTENDESK_OIDC_DISABLED=truebrings password sign-in back.The same release also makes the client ask for the console's TOTP (or emailed code) after a password, which had the same gap for accounts with 2FA. You can drop the reverse-proxy rule after upgrading.
Thanks for the clear report and for reading the code.