udServer uses the OAuth 2.0 Authorization Code flow with OpenID Connect (OIDC) for all user authentication. There is no built-in username/password login — every user authenticates through a configured identity provider (IdP).
At least one provider must be registered before anyone can log in. Until one is configured, /_user/whoami will return "needsAuthProvider": true and the server portal will prompt for initial setup.
/_oauth/login?provider=<id> and is redirected to the IdP's authorisation endpoint.{serverURL}/api/_oauth/redirect with an authorisation code.id_token (JWT), and reads the email and name claims.apikey) is set and the browser is sent to the portal.You need an OAuth 2.0 / OIDC-compliant identity provider. Any provider that supports the Authorization Code flow and returns an id_token with email and name claims will work. Common choices include:
Before adding a provider to udServer you must register udServer as an application (sometimes called a "client") in your IdP. The exact steps differ per IdP but you always need to configure:
Register the following URI as an allowed redirect (also called "callback URL"):
https://<your-udserver-hostname>/api/_oauth/redirect
The URI is case-sensitive and must match exactly, including the scheme (https://). If your server runs on a non-standard HTTPS port (e.g. 8443) include it:
https://<your-udserver-hostname>:8443/api/_oauth/redirect
The
serverURLsetting in udServer's configuration must resolve to the same base URL, because udServer constructs the redirect URI from it at runtime.
Request (or ensure the application is permitted to receive) the following scopes:
openidprofileemailoffline_accessudServer requests all four during the authorisation redirect. If email or profile (which provides name) are not present in the returned id_token, user creation and login will fail.
The application must be configured for the Authorization Code grant type. Implicit flow is not supported.
After registering the application you will need:
| Value | Where to find it |
|---|---|
| Client ID | Provided by the IdP after app registration |
| Client Secret | Generated during or after app registration |
| Authorisation Endpoint | From the IdP's OIDC discovery document (authorization_endpoint) |
| Token Endpoint | From the IdP's OIDC discovery document (token_endpoint) |
Most IdPs publish a discovery document at https://<idp-domain>/.well-known/openid-configuration that lists both endpoints.
| Field | Description |
|---|---|
id | Internal identifier used in API calls and login URLs. Lowercase, no spaces (e.g. entra, google). Minimum 3 characters. |
name | Display name shown to users in the portal login screen (e.g. Contoso Azure AD). Minimum 3 characters. |
authendpoint | Full URL of the IdP's authorisation endpoint |
tokenendpoint | Full URL of the IdP's token endpoint |
client_id | The client/application ID from the IdP |
client_secret | The client secret from the IdP |
When no providers are configured the /_auth/providers/add endpoint is publicly accessible to avoid a chicken-and-egg problem where you cannot log in to configure login. Once the first provider is successfully added this bootstrap access closes permanently; subsequent providers require the Server Config Edit global permission.
On first launch the udServer portal will detect that no auth provider is configured (needsAuthProvider: true) and present a setup form. Fill in the fields and submit.
Send a POST to https://<your-udserver-hostname>/api/_auth/providers/add:
{
"id": "entra",
"name": "Contoso Azure AD",
"authendpoint": "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize",
"tokenendpoint": "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token",
"client_id": "<application-client-id>",
"client_secret": "<application-client-secret>"
}
On success the server returns { "success": true }. You can now log in at:
https://<your-udserver-hostname>/api/_oauth/login?provider=entra
All provider management after first setup requires the Server Config Edit global permission. Use an account that already has that permission (typically the first admin user created during initial setup).
GET /api/_auth/providers/list
Without the Server Config Edit permission, only id and name are returned. With it, clientid, authendpoint, and tokenendpoint are also included (the client_secret is never returned).
POST /api/_auth/providers/add
Same body as the bootstrap call above.
POST /api/_auth/providers/remove
{ "id": "entra" }
Warning: If you remove the only configured provider, no one will be able to log in until the server is restarted.
Multiple providers are fully supported. Each must have a unique id. The portal login page will present a button for each configured provider. API clients specify which provider to use with the provider query parameter on /_oauth/login.
openid, profile, email, and offline_access delegated permissions are granted.https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration
https://accounts.google.com/o/oauth2/v2/authhttps://oauth2.googleapis.com/tokenhttps://<keycloak-host>/realms/<realm>/.well-known/openid-configuration
/#error=oauthfailureThis indicates the token exchange failed. Check that:
tokenendpoint URL is correct.client_id and client_secret are correct and the secret has not expired.{serverURL}/api/_oauth/redirect.serverURL configuration in udServer does not have a trailing slash and matches the scheme/host/port the browser used.If the redirect completes but no session is established, check the server logs for oauthfailure or nosession. This can occur if:
id_token returned by the IdP does not contain an email claim — ensure the email scope is granted.email claim is present but the account is deactivated in udServer."message": "malformed" on /_auth/providers/addAll six fields (id, name, authendpoint, tokenendpoint, client_id, client_secret) are required and must each be at least 3 characters long.
"message": "notallowed" on /_auth/providers/addAt least one provider is already configured and the request was made without a valid session that has the Server Config Edit global permission.