Nextcloud single sign-on with CodeB.
Use the CodeB OpenID Connect provider as the identity source for a self-hosted Nextcloud. One account, one password, auto-provisioning on first login, and per-user group mapping driven from CodeB’s admin UI. Cookie-free, PKCE-only, no client secrets to rotate.
Time to first login: about 10 minutes, including installing the Nextcloud app. Works against any Nextcloud version that ships the user_oidc app (Nextcloud 24+).
Read this before you wire OIDC to an existing Nextcloud user. Both user_oidc and the Social Login app default to overwriting a user’s Nextcloud groups with whatever the IdP sends in the groups claim on every login. If you attach OIDC to a user who already has carefully-managed local groups (admin rights, shared-folder ACLs, paid-plan group, etc.), their next sign-in will strip those groups and replace them with whatever CodeB sent. Locked-out admins and dropped permissions are the usual consequence.
Two safe ways to handle this — pick one before the first OIDC sign-in:
- Don’t emit groups from CodeB. In register.html, edit the affected users and leave the Groups field empty. With no
groupsclaim in the token, Nextcloud has nothing to overwrite the local groups with. (Recommended when Nextcloud is the source of truth for groups.) - Disable group sync in the Nextcloud app. See section 7. Per-user groups — the exact toggle differs between
user_oidcand Social Login.
In either case, decide who owns the group membership (Nextcloud or CodeB) before the user logs in. Don’t learn this the hard way after losing your admin group.
1. Prerequisites
- HTTPS on both ends. The CodeB IdP enforces HTTPS for any non-loopback redirect URI; Nextcloud’s callback URL must also be on HTTPS.
- Nextcloud reachable from a browser. The flow is browser-driven; Nextcloud doesn’t talk to the IdP directly — the user’s browser does the bouncing.
- Operator access to the CodeB host. You’ll create one file (
clients.json) on the IIS box that runs CodeB. No restart needed; the file is hot-reloaded. - One CodeB user account to test with. Created via the CodeB register.html admin page if you don’t have one yet.
2. Install the user_oidc app
In Nextcloud, go to Apps (top right user menu) and search for OpenID Connect user backend. Click Download and enable. After install you’ll see a new OpenID Connect section under Settings → Administration → User authentication.
The app is officially packaged by Nextcloud GmbH and is the recommended path. If your Nextcloud already has the Social Login app (sociallogin) installed and you prefer to keep using it, skip to the Alternative: Social Login app section — it works too, just with a different field layout.
3. Register your Nextcloud client on CodeB
The CodeB IdP requires every relying party to be pre-registered. Without an entry it returns invalid_client.
On the IIS host running CodeB, drop a JSON file at:
For example, on the public deployment at phone.codeb.io the path is D:\aloaha\phone\App_Data\phone.codeb.io\oidc\clients.json. Contents:
Both /index.php/apps/user_oidc/code and /apps/user_oidc/code are listed so the same file works regardless of whether your Nextcloud has the pretty-URL rewrite enabled. Include the port (e.g. :8443) if your Nextcloud isn’t on the default HTTPS port.
If you’re using the Social Login app instead, add its callback URL to the same redirect_uris array (one client entry can list as many URIs as you like). Social Login’s URL pattern is /index.php/apps/sociallogin/custom_oidc/<InternalName> — replace <InternalName> with whatever you put in that field (e.g. CodeBSSO).
Save the file. No IIS recycle is needed — the IdP mtime-checks the file and reloads it on the next OIDC request.
The built-in codeb-admin client is always available (auto-bound to https://<tenant>/oidc-callback.html) and does not need to be listed in clients.json. Only add third-party RPs.
4. Add the provider in Nextcloud (user_oidc app)
In Nextcloud: Settings → Administration → User authentication → OpenID Connect → Register new provider. Fill the form:
| Field | Value |
|---|---|
| Identifier | codeb (or any short label; this appears on the login button) |
| Client ID | nextcloud (must match what you put in clients.json) |
| Client secret | leave blank — CodeB is PKCE-only public client |
| Discovery endpoint | https://phone.codeb.io/.well-known/openid-configuration (or your CodeB host) |
| Scope | openid profile email |
| Use PKCE | on (S256). Mandatory. |
| Token endpoint auth method | none |
| Send id_token_hint on logout | on (recommended) |
Save. Nextcloud will fetch the discovery document and JWKS to confirm the provider is reachable.
5. Alternative: Social Login app (Custom OpenID Connect)
If your Nextcloud uses the Social Login app (sociallogin by zorn-v) instead of user_oidc, the form has different field names but the same flow. Settings → Administration → Social Login → Custom OpenID Connect → Add.
Social Login’s Custom OIDC provider does not use PKCE — it speaks classic OAuth 2.0 with a client_secret instead. Register your Nextcloud client as confidential in CodeB (put a client_secret in clients.json) and paste the exact same value into the Social Login form. The IdP automatically switches into client_secret_post mode when a secret is registered.
| Field | Value |
|---|---|
| Internal name | CodeBSSO (any short identifier; used internally only) |
| Title | CodeB SSO (appears on the login button) |
| Authorize url | https://<codeb-host>/oidc.ashx?action=authorize |
| Token url | https://<codeb-host>/oidc.ashx?action=token |
| Display name claim | name |
| User info URL | https://<codeb-host>/oidc.ashx?action=userinfo |
| Logout URL | https://<codeb-host>/oidc.ashx?action=end_session |
| Client Id | nextcloud (must match your clients.json entry from step 3) |
| Client Secret | A strong random value — generate at least 32 random chars (e.g. openssl rand -base64 48 or any password manager). Paste the same string into the client_secret field of clients.json on the CodeB side. CodeB constant-time compares them on every /token call. |
| Scope | openid profile email |
| Groups claim | groups |
| Button style | your pick (purely cosmetic) |
| Default group | leave None. The groups claim from CodeB already carries membership. |
Group mapping (CodeB → Nextcloud)
The Add group mapping button lets you translate the group names CodeB emits into the group names Nextcloud uses. Two ways to use it:
- Pass-through: leave it empty. CodeB’s groups (
admin,user,siponly,guest, plus any per-user custom groups) get auto-created in Nextcloud and the user joins them verbatim. - Map explicitly: one row per pair. The most common is mapping the CodeB
admingroup to Nextcloud’s built-inadmingroup so CodeB admins get full Nextcloud rights. Example rows:CodeB Nextcloud admin -> admin finance -> Finance Team ops -> Operations
The Logout URL is optional — CodeB is cookie-free so there’s no IdP-side session to clear, but filling it in still lets Nextcloud bounce the browser to end_session for a clean exit. Recommended.
Save. Sign out of Nextcloud, return to the login page, and click the CodeB SSO button (the title you set). The rest of the flow is identical to the user_oidc path — same CodeB login form, same auto-provisioning, same per-user group propagation.
6. Map claims
Further down the provider page, Nextcloud shows a Claim mapping section. Set:
| Mapping | Claim | What CodeB sends |
|---|---|---|
| User ID | sub | The CodeB username (e.g. alice). Stable, used as the Nextcloud account ID. |
| Display name | name | From the user’s OIDC profile (the Full name field in CodeB’s register.html). |
email | From the OIDC profile. Make sure it’s populated — Nextcloud notification emails depend on it. | |
| Quota | leave blank | CodeB doesn’t emit a quota claim. |
| Groups | groups | Array of strings. Defaults to a single-element array with the role (["admin"], ["user"], etc.). Override per user (see next section). |
Finally, enable Auto-provisioning (or whatever the toggle is called in your Nextcloud version). When a CodeB user signs in for the first time, Nextcloud creates the local account on the fly.
7. Per-user groups
CodeB has four built-in roles (admin / user / siponly / guest) that arrive in the groups claim as a single-element array. That works for the simple case but is rarely what you want in Nextcloud, where group membership drives shares, talk-permissions, file quotas, and so on.
Override per user in the CodeB admin UI. In register.html, click Edit on a user, scroll to the Groups section, and enter a comma-separated list:
Save. From the next sign-in onward, the groups claim arrives at Nextcloud as ["finance", "nextcloud-admin", "ops"] instead of the role-derived default. The user_oidc app auto-creates any Nextcloud groups that don’t exist yet, and assigns the user accordingly.
Constraints: up to 32 groups per user, each 1–64 chars from a-zA-Z0-9_.-. Empty list means “fall back to the role-as-group default.”
Don’t overwrite existing group memberships
Both Nextcloud OIDC apps rewrite the user’s entire group list on every login by default. If the user already belongs to Nextcloud groups that you don’t want OIDC to touch (admin, share recipients, license groups), choose ONE of the two postures below before the first OIDC sign-in.
Posture A — let Nextcloud own groups, don’t emit them from CodeB
This is the simplest. In CodeB’s register.html, leave the Groups field empty for any user whose Nextcloud groups you don’t want overwritten. Without a populated groups field, CodeB falls back to a single-element [role] array. To suppress even that, you can request a scope that excludes groups on the Nextcloud side — but the simpler move is the next posture.
Posture B — emit groups from CodeB, disable sync in Nextcloud
Different toggle per app:
| App | Setting to turn OFF | Where |
|---|---|---|
user_oidc |
Provide updated user information from the IDP at each login → turn off Groups | Settings → Administration → OpenID Connect → the provider → Mappings (the “Update at login” checkbox row for the groups mapping) |
| Social Login | Uncheck Update user profile every login AND clear the Groups claim field (or set it to an unused claim name like nogroups) |
Settings → Administration → Social Login → the Custom OIDC provider → bottom of the form |
With either toggle off, the OIDC login still authenticates the user and updates display name + email if those mappings are on, but it stops touching group membership. Group changes are then administered in Nextcloud itself.
Test this before going live. Sign in as a throwaway test user first — one whose group loss you can afford. Confirm in Settings → Users that the test user’s groups match what you expect. Only then turn on OIDC for real accounts.
8. Test the round trip
- Open an incognito Nextcloud tab and click Log in with codeb (the label you set in step 4).
- Your browser bounces to
https://phone.codeb.io/login.html. - Enter a CodeB username + password. The browser hashes the password to HA1 locally and posts only the hash — CodeB never sees the plaintext.
- On success, you land back at Nextcloud, signed in. First-time login auto-provisions a Nextcloud account with the claims above.
Verify in Nextcloud: top-right user menu shows the display name and email. Settings → Administration → Users shows the new user with the OIDC backend label and the configured groups.
9. Make a Nextcloud admin out of a CodeB user
Nextcloud’s built-in admin group grants full admin rights. To map a CodeB user to it, add admin as one of their groups in CodeB:
That puts them in Nextcloud’s admin group on the next sign-in. (The Nextcloud built-in “admin” group is just a plain group with special privileges — the groups claim creates membership the same way as any other group.)
Don’t confuse this with the CodeB role claim. A CodeB user with role: "user" who has admin in their groups list becomes a Nextcloud admin but is still a non-admin in CodeB’s own admin pages. The two systems’ permission models are independent.
10. Troubleshooting
| Symptom | Cause |
|---|---|
invalid_client at /authorize |
The client_id isn’t in clients.json, or the redirect_uri Nextcloud sent doesn’t match any of the registered URIs byte-for-byte. Check Nextcloud’s data/nextcloud.log for the exact URI it sent, then add it to clients.json. |
Social Login: invalid_client with no obvious cause |
The Social Login app posts back to https://<nextcloud>/index.php/apps/sociallogin/custom_oidc/CodeBSSO (where CodeBSSO is your Internal name). That whole URL must be in your clients.json redirect_uris array. If you renamed the internal name, the redirect URI changes too. |
Social Login: invalid_request at /authorize |
Means CodeB still thinks your client is public PKCE-only but Social Login isn’t sending a code_challenge. Add a non-empty client_secret to the client entry in clients.json — the IdP then treats the client as confidential and accepts the request without PKCE. |
Social Login: invalid_client: client_secret invalid |
The secret in Nextcloud’s provider form doesn’t match the client_secret in clients.json. They must be byte-for-byte identical. Be careful with trailing whitespace and quotes when copy-pasting. |
invalid_grant: PKCE verifier invalid |
Make sure Use PKCE is on in the Nextcloud provider settings. Without PKCE the IdP rejects the auth code. |
| “Could not load user” after sign-in | Auto-provisioning is off. Toggle it on in the provider settings and retry. |
| User created but no email / no name | The CodeB profile doesn’t have email / name set. Edit the user in register.html and fill those fields, then sign in again. |
| Groups don’t appear in Nextcloud | (a) Make sure the Groups claim mapping is set to groups in step 5. (b) If using per-user override, double-check the names match the constraint (a-z A-Z 0-9 _ . -). (c) Nextcloud only refreshes groups on each sign-in; sign out and back in. |
429 rate_limited during testing |
The CodeB login endpoint allows 10 failed attempts per IP per minute. Wait a minute (honour Retry-After) and try again. |
Need help? Get in touch — we run Nextcloud SSO with CodeB in production and can help debug your install.