OAuth¶
OAuth authentication is a separate plugin, not bundled with 3forge Enterprise: request and install it, then point 3forge Enterprise's SSO extension point at it along with your provider's OAuth client details. This is a browser-redirect login, not a username-and-password check, so it works for the Web only; see Authentication -> Two plugin mechanisms, not one if you need REST or WebSocket clients authenticated too.
Configuring the connection¶
Register a web application with your OAuth provider first, so you have a client ID, a client secret, and a redirect URI to give it. Then set sso.plugin.class, the URL that triggers the redirect, and the provider's endpoints, and restart:
oauth.redirect.uri must exactly match the redirect URI registered with the provider: most providers reject the login attempt outright if the two differ by so much as a trailing slash.
After restarting, open the Web's address in a browser, and the login redirects to the provider. A successful login redirects back into the Web already signed in; a rejected one is turned back by the provider before 3forge Enterprise sees anything to accept or reject.
Provider requirements¶
- Set every endpoint for a provider other than Okta: The defaults are Okta-style paths (
/oauth2/default/v1/authorize,/oauth2/default/v1/token, and/oauth2/default/v1/logout), andoauth.refresh.token.endpointdefaults to the token path. - Allow offline tokens, or drop the scope: The default scope is
openid profile email offline_access, andoffline_accessasks for a refresh token. A provider can reject the token request with an error such asOffline tokens not allowed for the user or client, so allow offline tokens at the provider or setoauth.scopewithoutoffline_access. - ID token claims become user attributes: Each claim is added to the user's attributes as
amiscript.variable.<claim>, for exampleamiscript.variable.email.
Mapping OAuth claims to roles¶
Set a role property to the OAuth/OIDC claim name that carries it, then a values property to say which values mean "yes":
Set the field and values properties together. A field without its values property fails the sign-in with an error.
To grant attributes by role, name the roles 3forge Enterprise recognizes, where the token carries them, and what each role grants:
The default role grants all of its attributes. Every other enabled role the user holds adds only its LAYOUTS. If the default role is not enabled, the first enabled role in the user's list becomes the default. A user with no enabled role is rejected at login. Claim names can be nested with a dot.
Refreshing an expired session¶
oauth.access.token.expires.in: the name of the field in the provider's token response that carries the token lifetime. It defaults toexpires_in. If the response has no such field, the token is treated as never expiring, and the session does not poll for a new one.oauth.refresh.token.endpoint,oauth.refresh.grant.type,oauth.refresh.scope: the endpoint and parameters used to refresh a token without asking the user to sign in again.oauth.single.logout.enabledplusoauth.logout.endpoint,oauth.logout.redirect.uri: end the session at the provider, not just in 3forge Enterprise, when a user logs out. Single logout takes effect only whenoauth.logout.redirect.uriis set.
An open session polls every oauth.session.check.period.seconds and renews its access token at the refresh endpoint. The session ends if the renewal fails, so set oauth.refresh.token.endpoint to the provider's token endpoint.
Other properties¶
| Property | Default | Purpose |
|---|---|---|
oauth.debug |
false |
Logs the authorization exchange in detail. With it on, the log records the token request, including its Authorization header, which encodes the client secret. Turn it off after setup |
oauth.validate.certs |
true |
Validates the provider's TLS certificate on token and refresh requests |
oauth.dynamic.redirect |
false |
Builds the redirect URI from the address the browser used to reach the Web, keeping the path from oauth.redirect.uri |
oauth.session.check.period.seconds |
60 |
How often an open session renews its access token |
oauth.refresh.client.id |
oauth.client.id |
Client ID sent on the refresh request |
oauth.refresh.client.secret |
oauth.client.secret |
Client secret sent on the refresh request |
oauth.refresh.redirect.uri |
none | Sent as redirect_uri on the refresh request when set |
oauth.code.challenge.method |
S256 (when unset) |
PKCE code challenge method. Leave it unset: the plugin also reads this key as the digest algorithm name, so setting it, even to S256, breaks the code challenge |
What this page does not cover¶
Okta has its own, separate authentication plugin: a different class, which reads a subset of the same oauth.* properties. It is not a variant of this plugin, and installing it doesn't require this plugin's jar. See Okta for configuring it.
What this does not support¶
- No REST or WebSocket login: OAuth here is a browser-redirect flow, which a REST or WebSocket client cannot follow, so this plugin authenticates the Web only.
- No single sign-on discovery: there is no property for a
.well-knownOpenID configuration URL, so every endpoint (oauth.authorization.endpoint,oauth.token.endpoint, and the rest) is set individually.