Skip to main content
Alginte’s single sign-on uses standard OpenID Connect (authorization-code flow). Any OIDC-compliant provider works; the walkthroughs below cover four common ones.

What Alginte needs from any provider

Register Alginte at your provider as a confidential web application (not a public/SPA client — Alginte’s backend performs the code-for-token exchange server-side). That registration yields three artifacts:
  1. Client id and client secret.
  2. Issuer URI — the provider’s realm/tenant base URL. Alginte discovers every endpoint from <issuer>/.well-known/openid-configuration at startup — which is also why the backend refuses to start if the provider is unreachable.
  3. A registered redirect URI: http(s)://<alginte-host>/login/oauth2/code/<registration-id>. The <registration-id> is a name you choose (e.g. keycloak, google, entra, okta) — it appears in the property keys below, on the login button (“Sign in with <registration-id>”), and in the callback path.
Request the scopes openid, profile, email — the email claim powers the allowlist’s domain matching.

The property block

Every property can also be an environment variable (uppercase, dots → underscores, dashes removed — see Configuration). For a Docker deployment that keeps the secret out of any file:
Keep the client secret out of version control — supply it via an environment variable or a file excluded from your repo.

The allowlist is not optional

A bare OIDC login admits anyone the provider authenticates — every Gmail account, every user in the tenant. Alginte therefore fails startup if OIDC is configured without alginte.auth.allowed-users / allowed-domains.
  • allowed-users entries match the provider-asserted username or email.
  • allowed-domains entries match the email’s domain.
  • Matching is case-insensitive; empty lists admit nobody.
  • A user who authenticates at the provider but isn’t allowlisted is bounced back to the login screen with an explicit message and no session.
With multiple providers, the allowlist is shared across all of them — one list for the whole instance, not per provider.

Provider walkthroughs

  1. In your realm: Clients → Create client — OpenID Connect, client authentication on (confidential), standard flow only.
  2. Register the redirect URI https://<alginte-host>/login/oauth2/code/keycloak.
  3. Copy the client secret from the Credentials tab.
  4. Issuer: https://<keycloak-host>/realms/<realm>.
  5. Add spring.security.oauth2.client.provider.keycloak.user-name-attribute=preferred_username so the allowlist can match Keycloak usernames (the default claim is the opaque sub).

Behind a reverse proxy (HTTPS)

Spring computes the redirect URI from the incoming request, so behind a TLS-terminating proxy the public URL must be what Spring sees:
  1. Forward the standard X-Forwarded-* headers from the proxy.
  2. Set server.forward-headers-strategy=framework (env: SERVER_FORWARDHEADERSSTRATEGY=framework).
  3. Register the public https://... redirect URI at the provider.
Symptom of getting this wrong: the provider rejects the login with a redirect-URI-mismatch error, because Spring built an internal http:// URL.

Multiple providers

Registrations are additive: configure several spring.security.oauth2.client.registration.<id>.* blocks and the login screen renders one “Sign in with <id>” button per registration. The single-account username/password login composes with all of them.
The allowlist is shared, and a list property is replaced, not merged, by whichever configuration source wins — so the winning source must carry the full list for all providers (e.g. allowed-users=alice,you@gmail.com), not just the newest provider’s entry.

Troubleshooting

SymptomCause
Backend refuses to start; message names the allowlistOIDC registration present but alginte.auth.allowed-users / allowed-domains empty — the deliberate fail-fast guard.
Backend refuses to start; connection error during startupIssuer discovery failed — the provider is unreachable or the issuer-uri is wrong.
Provider shows a redirect-URI-mismatch errorThe URI registered at the provider doesn’t match what Spring computed — check host, scheme (see the reverse-proxy section), and the <registration-id> in the path.
Login screen shows “not on the Alginte allowlist”Authentication succeeded, the allowlist rejected — check which claim you’re matching: allowed-users compares the username (the user-name-attribute claim) or email; allowed-domains the email domain.
One provider works, a second is always rejectedThe shared allowlist was replaced by the newest configuration source — carry the full list in whichever source wins (see Multiple providers).
Sign-out, then re-login without a password promptExpected: logout ends the app session, not the provider’s SSO session.