Authentication¶
3forge Enterprise has 2 separate plugin mechanisms for external identity, not one, and picking the wrong one for a given provider is the most common way to get stuck. Both mechanisms are configured entirely through property files, restarting to pick up the change: there is no admin panel or REST endpoint for setting this up, so delegating authentication to a corporate directory or identity provider is a deployment step, not a runtime one. Authentication controls who a user is; for what an authenticated user can then see and do, see Security.
Features¶
- Check credentials against a real directory: an LDAP plugin validates the username and password a client sends, the same way the shipped default does, so REST and WebSocket clients keep sending plain credentials.
- Redirect logins to a SAML or Okta identity provider: a browser signing into the Web is redirected to your identity provider and back, so nobody types a password 3forge Enterprise itself checks.
- Map directory attributes onto 3forge Enterprise roles: an LDAP or SAML attribute can set a user's admin flag, dev flag, layout, or session limit automatically, so provisioning happens in the directory, not in 3forge Enterprise.
- Secure by default: a fresh install has no external identity provider reachable until you configure one; the shipped default authenticates against a local file.
Two plugin mechanisms, not one¶
ami.auth.plugin.class checks a username and password directly. It's what the shipped defaults (ACCESS_FILE, DISABLED) use, and it's what LDAP uses too: whichever surface a login comes through (the Web, the REST API with Authorization: Basic, or a WebSocket client passing credentials in the connection URL), the plugin sees the same username and password and returns the same outcome.
sso.plugin.class is a different mechanism entirely: a browser is redirected to an external identity provider, which redirects it back once the person has signed in there. 3forge Enterprise never sees a password to check. This is what SAML, Okta, and generic OAuth use, and it works for the Web only: there's no way for a REST script or a WebSocket client to be "redirected" the way a browser is, so none of the 3 can authenticate a REST or WebSocket client.
| Identity provider | Mechanism | Page |
|---|---|---|
| LDAP directory | ami.auth.plugin.class (same as REST/WebSocket) |
LDAP |
| SAML identity provider | sso.plugin.class (Web only) |
SAML |
| OAuth / OpenID Connect | sso.plugin.class (Web only) |
OAuth |
| Okta | sso.plugin.class (Web only), a separate plugin from generic OAuth |
Okta |
Only one plugin can be active per mechanism: one ami.auth.plugin.class, and separately, one sso.plugin.class. You can't run 2 SSO providers side by side, and you can't have LDAP and an SSO provider both live at once for the same login attempt.
Whether the generic OAuth plugin is currently available as a built, requestable artifact is unconfirmed (tracked as A-03); see that page for detail.
What a rejected login looks like¶
For an ami.auth.plugin.class login (the shipped defaults or LDAP) over REST, a bad username and a bad password look identical on the wire: both come back as the literal body text BAD_CREDENTIALS with HTTP 401, deliberately not telling a caller which part was wrong. A general error (the identity provider unreachable, for example) is INTERNAL_ERROR with HTTP 500. An sso.plugin.class login (SAML, Okta, OAuth) either succeeds or is rejected by the identity provider itself, before 3forge Enterprise is involved at all; there's no equivalent 2-outcome split for that path.