glpi: REST auth recipe (app_token + encrypted-at-rest trap), SSO script known-issue
GLPI 11 encrypts api/app tokens at rest and decrypts before comparing; the DB ciphertext never authenticates. Document the working initSession?user_token+app_token recipe, per-user token minting via GLPIKey, REST account provisioning, and the singlesignon plugin callback breakage. https://projects.knownelement.com/issues/947#note-5519
This commit is contained in:
@@ -143,7 +143,7 @@ scripts/discourse-sso-login.sh <username> [vault-item] # /auth/oidc (+ CSRF +
|
||||
|
||||
| System | SSO start point | Gotchas |
|
||||
|---|---|---|
|
||||
| GLPI | `https://cmdb.knownelement.com/plugins/singlesignon/front/callback.php/provider/1?remember=1` | account auto-provisioned; no scripted flow yet |
|
||||
| GLPI | `https://cmdb.knownelement.com/plugins/singlesignon/front/callback.php/provider/1?remember=1` | script exists (`glpi-sso-login.sh`) but the plugin callback is BROKEN on GLPI 11 (include-path + session/CSRF Access denied) — provision accounts via REST instead (recipe below) |
|
||||
| Gitea | `https://git.knownelement.com/user/oauth2/cloudron` | redirects to `client_id=<app-uuid>-oidc`; gitea may NORMALIZE the username (e.g. `tsgstaff-coo-vpperf` → `vpperf`) — verify which login got created |
|
||||
| Discourse | `https://community.turnsys.com/auth/oidc` | hostname is community.**turnsys.com**; provider name is `oidc`, NOT openid_connect; needs `/session/csrf` token then a confirm-page authenticity_token POST |
|
||||
| Redmine | `https://projects.knownelement.com/oauth?oauth_provider=1` | the "bounce to /login" mystery = the plugin's GET form needs `oauth_provider=1` |
|
||||
@@ -188,9 +188,22 @@ centrally — no per-identity session needed:
|
||||
`/admin/users/list/active.json` first. Admin Api-Key minting uses the same
|
||||
model; admin key for vptechops is in `creds/vptechops-discourse`
|
||||
(`admin_api_key`).
|
||||
- **GLPI**: DEFERRED on #947 — REST `user_token` auth 401s even for a
|
||||
super-admin with api_token/personal_token set; do not burn time re-deriving
|
||||
that failure.
|
||||
- **GLPI** (WORKING as of 2026-09-09, #947 root-caused): REST needs BOTH
|
||||
`user_token` AND `app_token`:
|
||||
`GET /apirest.php/initSession?user_token=<plaintext user api_token>&app_token=<plaintext app_token>`
|
||||
→ `session_token`; then `Session-Token:` + `App-Token:` headers. THE TRAP:
|
||||
GLPI 11 ENCRYPTS tokens at rest (`are_apiclients_tokens_encrypted` /
|
||||
`are_users_tokens_encrypted`, sodium XChaCha20, key `/app/data/config/glpicrypt.key`)
|
||||
and DECRYPTS before comparing — the ciphertext you see in
|
||||
`glpi_users.api_token` / `glpi_apiclients.app_token` NEVER authenticates.
|
||||
Plaintext values: app_token = `creds/glpi` password; glpi super-admin
|
||||
api_token = `creds/glpi` username; per-user tokens are vaulted in each
|
||||
identity's master item (`glpi_api_token`). To mint: `openssl rand -hex 20`,
|
||||
encrypt with `GLPIKey('/app/data/config')->encrypt()` inside the
|
||||
container, write back via SQL (plaintext legacy rows never authenticate).
|
||||
Create accounts via REST as the glpi super-admin (`POST /User` with
|
||||
name/email matching the Cloudron identity) — the SSO plugin's
|
||||
auto-register is broken on GLPI 11 (#947).
|
||||
|
||||
Store each key in the vault item immediately (schema below), and always
|
||||
verify the write (`sm get … --field …` readback) — `sm setfield` 400s
|
||||
|
||||
Reference in New Issue
Block a user