SSO Configuration with OpenID Connect

Overview

Fess supports Single Sign-On (SSO) authentication using OpenID Connect (OIDC). OpenID Connect is an authentication protocol built on top of OAuth 2.0 that uses ID Tokens (JWT) for user authentication. By using OpenID Connect authentication, user information authenticated by an OpenID Provider (OP) can be integrated with Fess.

Note

OpenID Connect authentication comes from the fess-sso-oidc plugin, which is not part of the distribution. Install it from the System > Plugin page in the administration screen, or with bin/fess-setup install plugin fess-sso-oidc. The plugin is named fess-sso-oidc while the sso.type value stays oic. Until it is installed, sso.type=oic only redirects every request to /sso/ back to the login page.

How OpenID Connect Authentication Works

In OpenID Connect authentication, Fess operates as a Relying Party (RP) and collaborates with an external OpenID Provider (OP) for authentication.

  1. User accesses the Fess SSO endpoint (/sso/)

  2. Fess redirects to the OP’s authorization endpoint

  3. User authenticates at the OP

  4. OP redirects the authorization code to Fess

  5. Fess uses the authorization code to obtain an ID Token from the token endpoint

  6. Fess decodes the ID Token (JWT), checks its claims, extracts user information and logs in the user

Note

Fess uses the Authorization Code Flow. The ID Token is obtained directly from the token endpoint via a back-channel (server-to-server communication) between Fess and the OP, without passing through the browser. Fess decodes the ID Token and extracts claims (such as email and groups) to construct user information, but does NOT cryptographically verify the JWT signature. OpenID Connect Core allows this because the token is received directly from the token endpoint over TLS, so the token endpoint URL (oic.token.server.url) must be HTTPS. http is accepted only for localhost, 127.x.x.x and ::1. Fess does check the claims: aud must contain oic.client.id (and azp, when present, must equal it), exp must be present and not past (a clock difference of up to 300 seconds is tolerated), and iss must equal oic.issuer when that key is set. Without oic.issuer, iss is not checked, and a warning is logged at the first login after each start. nonce and PKCE are not used.

For integration with role-based search, see Role-Based Search Configuration.

Prerequisites

Before configuring OpenID Connect authentication, verify the following prerequisites:

  • Fess 15.9 or later is installed

  • An OpenID Connect-compatible provider (OP) is available

  • Fess is accessible via HTTPS (required for production environments)

  • You have permission to register Fess as a client (RP) on the OP side

Examples of supported providers:

  • Microsoft Entra ID (Azure AD)

  • Google Workspace / Google Cloud Identity

  • Okta

  • Keycloak

  • Auth0

  • Other OpenID Connect-compatible providers

Basic Configuration

Enabling SSO

To enable OpenID Connect authentication, add the following setting to app/WEB-INF/conf/system.properties:

sso.type=oic

Note

The sso.type setting and the oic.* settings described below, except oic.issuer, can also be configured and changed from the admin “System > General” page. Settings changed through the admin page are saved to system.properties and persist after restart. oic.issuer can only be set in system.properties.

Provider Configuration

Configure the information obtained from your OP.

Property Description Default
oic.auth.server.url Authorization endpoint URL https://accounts.google.com/o/oauth2/auth
oic.token.server.url Token endpoint URL https://accounts.google.com/o/oauth2/token
oic.issuer Issuer identifier (optional). When set, the iss claim of the ID Token must equal it exactly (a trailing slash counts) (empty: iss is not checked)

Note

These URLs and the issuer can be obtained from the OP’s Discovery endpoint (/.well-known/openid-configuration); the issuer is its issuer value. The token endpoint URL (oic.token.server.url) must be HTTPS. http is accepted only when the host is localhost (any case), an IPv4 address of the form 127.x.x.x, or ::1. The host is compared as written and is never resolved, so a Docker Compose service name (such as http://keycloak:8080/...) or an internal host name is refused over http even if it points to the same machine.

Only the token endpoint is checked, not the authorization endpoint (oic.auth.server.url). The check runs at login, not at startup. Setting oic.issuer does not relax this rule; it only turns on the check of the iss claim.

Client Configuration

Configure the client information registered with the OP.

Property Description Default
oic.client.id Client ID (empty)
oic.client.secret Client secret (empty)
oic.scope Requested scopes (empty)

Note

The scope must include at least openid. To retrieve the user’s email address, specify openid email.

Redirect URL Configuration

Configure the callback URL after authentication.

Property Description Default
oic.redirect.url Redirect URL (callback URL) {oic.base.url}/sso/
oic.base.url Fess base URL http://localhost:8080

Note

If oic.redirect.url is omitted, it is automatically constructed from oic.base.url. For production environments, set oic.base.url to an HTTPS URL.

User Attribute Configuration

Configure the default groups and roles to assign to users authenticated via OIDC. The user ID, groups, and roles are determined as follows:

  • User ID: Obtained from the email claim of the ID Token (JWT). For this reason, the email scope is effectively required (if the email claim cannot be obtained, login will not work correctly).

  • Groups: Obtained from the groups claim of the ID Token. If the groups claim is not present, the value of oic.default.groups is used. An empty groups array counts as present, so oic.default.groups is not used and the user is treated as having no groups.

  • Roles: Always taken from the value of oic.default.roles (there is no mechanism to obtain roles from ID Token claims).

Note

Fess uses the values of the groups claim as they are; it performs no directory lookup and does not expand nested (transitive) groups. Whether parent groups appear is therefore decided entirely by the OP’s claim configuration – unlike SSO Configuration with Entra ID, where Fess resolves parent groups through the Microsoft Graph API. The claim value becomes the search permission verbatim. A provider configured to emit full group paths therefore sends values such as /parent/child, and those do not match documents tagged with the plain group name.

Property Description Default
oic.default.groups Default groups (comma-separated) (empty)
oic.default.roles Default roles (comma-separated) (empty)

Note

When using role-based search, you must assign appropriate groups or roles to users. See Role-Based Search Configuration for details.

OP-Side Configuration

When registering Fess as a client (RP) on the OP side, configure the following information:

Setting Value
Application type Web application
Redirect URI / Callback URL https://<Fess host>/sso/
Allowed scopes openid and required scopes (email, profile, etc.)

Information to Obtain from OP

Obtain the following information from the OP’s configuration screen or Discovery endpoint for use in Fess configuration:

  • Authorization Endpoint: URL to initiate user authentication

  • Token Endpoint: URL to obtain tokens

  • Issuer (optional): issuer value of the Discovery document, used for oic.issuer

  • Client ID: Client identifier issued by the OP

  • Client Secret: Secret key used for client authentication

Note

Most OPs allow you to check the authorization and token endpoint URLs from the Discovery endpoint (https://<OP>/.well-known/openid-configuration).

Configuration Examples

Minimal Configuration (for Testing)

The following is a minimal configuration example for verification in a test environment.

# Enable SSO
sso.type=oic

# Provider configuration (set values obtained from OP)
oic.auth.server.url=https://op.example.com/authorize
oic.token.server.url=https://op.example.com/token

# Client configuration
oic.client.id=your-client-id
oic.client.secret=your-client-secret
oic.scope=openid email

# Redirect URL (test environment)
oic.redirect.url=http://localhost:8080/sso/

Troubleshooting

Common Problems and Solutions

Cannot Return to Fess After Authentication

  • Verify that the redirect URI is correctly configured on the OP side

  • Ensure that the oic.redirect.url or oic.base.url value matches the OP configuration

  • Verify that the protocol (HTTP/HTTPS) matches

Authentication Errors Occur

  • Verify that the client ID and client secret are correctly configured

  • Ensure that the scope includes openid

  • Verify that the authorization endpoint URL and token endpoint URL are correct

  • If login fails, fess.log contains a warning Failed to process the OpenID Connect callback: followed by the reason

  • The ID token was not issued for this client: aud of the ID Token is not oic.client.id; check the client ID

  • The ID token has expired: the clocks of the Fess host and the OP differ by more than 300 seconds; synchronize the time (NTP)

  • The ID token was not issued by the configured issuer: oic.issuer differs from the iss shown in the message; copy the issuer value of the Discovery document exactly

  • oic.token.server.url must be https: use an HTTPS token endpoint URL (http works only for localhost, 127.x.x.x and ::1; http to a Docker Compose service name or an internal host name is refused too)

Cannot Retrieve User Information

  • Ensure that the scope includes the required permissions (email, profile, etc.)

  • Verify that the required scopes are allowed for the client on the OP side

  • With Microsoft Entra ID, the groups claim carries group ObjectId GUIDs unless a different source attribute is selected, so the values will not match group names

  • Microsoft Entra ID omits the groups claim entirely when the user belongs to more than 200 groups (nested groups count toward this limit), and Fess then falls back to oic.default.groups

Debug Configuration

To investigate problems, you can output detailed OpenID Connect-related logs by adjusting the Fess log level.

In app/WEB-INF/classes/log4j2.xml, add the following logger to change the log level:

<Logger name="org.codelibs.fess.sso.oic" level="DEBUG"/>

Warning

With this logger at DEBUG, the claims of the ID Token (such as email and groups) are written to the log file. Restore the log level once the investigation is over, and handle the log output accordingly.

Reference