How to Configure OAuth2 Authentication in Stirling-PDF: Enterprise SSO Guide
Enable OAuth2 in Stirling-PDF by setting security.oauth2.enabled: true in settings.yml, configuring provider-specific client credentials, and ensuring the redirect URI {baseUrl}/login/oauth2/code/{registrationId} is registered with your identity provider.
Stirling-PDF supports OAuth2 Single Sign-On (SSO) through external identity providers such as Google, GitHub, Keycloak, or any generic OpenID Connect server. This guide explains how to configure OAuth2 authentication in Stirling-PDF based on the actual implementation in the Stirling-Tools/Stirling-PDF repository.
Understanding the OAuth2 Architecture in Stirling-PDF
The OAuth2 implementation consists of three distinct layers that handle configuration, security registration, and UI rendering.
Configuration Layer: ApplicationProperties.java
All OAuth2 settings are loaded from settings.yml into the Security.OAUTH2 inner class inside [ApplicationProperties.java](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java). This POJO maps YAML properties such as security.oauth2.enabled, client.google.clientId, and useAsUsername to Java objects used by the security layer.
Security Layer: OAuth2Configuration.java
The [OAuth2Configuration.java](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java) class constructs ClientRegistration objects for each enabled provider and registers them with Spring Security’s InMemoryClientRegistrationRepository. The validateProvider() method ensures each configured provider has valid credentials before registration, while clientRegistrationRepository() exposes the repository bean to the Spring Security filter chain.
Frontend Layer: OAuthButtons.tsx
The React component [OAuthButtons.tsx](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/frontend/src/proprietary/routes/login/OAuthButtons.tsx) renders login buttons for each provider exposed by the backend API. Each button links to /oauth2/authorization/{registrationId}, triggering the standard Spring Security OAuth2 redirect flow.
Step-by-Step Configuration Guide
Enable OAuth2 Globally
Edit settings.yml to enable the OAuth2 module and define which user attribute to map as the internal username:
security:
oauth2:
enabled: true
useAsUsername: email
The useAsUsername field accepts values such as email or preferred_username depending on your identity provider’s claims.
Configure Google OAuth2
Add the Google provider block under security.oauth2.client:
security:
oauth2:
client:
google:
clientId: ${GOOGLE_CLIENT_ID}
clientSecret: ${GOOGLE_CLIENT_SECRET}
scopes:
- openid
- profile
- email
Configure GitHub OAuth2
GitHub uses OAuth rather than OIDC, requiring specific scopes for user data access:
security:
oauth2:
client:
github:
clientId: ${GITHUB_CLIENT_ID}
clientSecret: ${GITHUB_CLIENT_SECRET}
scopes:
- read:user
- user:email
Configure Generic OIDC (Keycloak Example)
For Keycloak or any standard OIDC provider, use the provider and issuer fields:
security:
oauth2:
provider: keycloak
issuer: https://keycloak.example.com/realms/myrealm
useAsUsername: preferred_username
client:
keycloak:
clientId: ${KC_CLIENT_ID}
clientSecret: ${KC_CLIENT_SECRET}
scopes:
- openid
- profile
- email
The provider value becomes the registrationId used in the redirect URI path.
Auto-Create Users on First Login
To automatically provision internal user accounts when new users authenticate via OAuth2:
security:
oauth2:
autoCreateUser: true
When false, only existing Stirling-PDF users can log in via OAuth2.
Restart and Verify
- Restart the application to trigger
OAuth2Configuration.clientRegistrationRepository()validation - Verify the redirect URI format
{baseUrl}/login/oauth2/code/{registrationId}is registered with your identity provider (e.g.,https://pdf.example.com/login/oauth2/code/google) - Check that
OAuthButtons.tsxrenders buttons linking to/oauth2/authorization/{registrationId}
Complete Configuration Example
# settings.yml – Production-ready OAuth2 configuration
security:
enableLogin: true
oauth2:
enabled: true
useAsUsername: email
autoCreateUser: true
client:
google:
clientId: ${GOOGLE_CLIENT_ID}
clientSecret: ${GOOGLE_CLIENT_SECRET}
scopes:
- openid
- profile
- email
github:
clientId: ${GITHUB_CLIENT_ID}
clientSecret: ${GITHUB_CLIENT_SECRET}
scopes:
- read:user
- user:email
provider: keycloak
issuer: https://keycloak.example.com/realms/production
client:
keycloak:
clientId: ${KC_CLIENT_ID}
clientSecret: ${KC_CLIENT_SECRET}
scopes:
- openid
- profile
- email
Environment variables (${...}) are resolved at runtime via Spring Boot’s relaxed binding, keeping secrets out of version control.
Key Source Files Reference
-
ApplicationProperties.java– Defines theSecurity.OAUTH2configuration model that mapssettings.ymlproperties to Java objects. Located atapp/common/src/main/java/stirling/software/common/model/ApplicationProperties.java. -
OAuth2Configuration.java– ConstructsClientRegistrationbeans and registers them with Spring Security’sInMemoryClientRegistrationRepository. Located atapp/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java. -
OAuthButtons.tsx– React component that renders OAuth provider buttons linking to/oauth2/authorization/{registrationId}. Located atfrontend/src/proprietary/routes/login/OAuthButtons.tsx. -
DesktopOAuthButtons.tsx– Desktop-specific OAuth UI for the Tauri client. Located atfrontend/src/desktop/components/SetupWizard/DesktopOAuthButtons.tsx. -
TauriOAuthUtils.java– Utility class handling OAuth callbacks for the desktop application. Located atapp/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/TauriOAuthUtils.java.
Troubleshooting Common OAuth2 Issues
No Login Buttons Appear
Symptom: The OAuth2 login buttons do not display on the login page.
Cause: security.oauth2.enabled is false or the settings.yml file cannot be loaded from the path resolved by InstallationPathConfig.getSettingsPath().
Fix: Verify the YAML syntax and ensure oauth2.enabled: true is set under the security block.
"Invalid Client" or Redirect URI Mismatch Errors
Symptom: The identity provider returns an error about invalid clients or redirect URIs.
Cause: The redirect URI is not registered in the provider’s OAuth2 console.
Fix: Register the exact URI format used by OAuth2Configuration.REDIRECT_URI_PATH: {baseUrl}/login/oauth2/code/{registrationId}. For example, https://pdf.example.com/login/oauth2/code/google.
Login Succeeds but User Is Not Created
Symptom: Authentication succeeds at the provider, but Stirling-PDF shows an error or redirects back to login.
Cause: The user does not exist in the local database and autoCreateUser is disabled.
Fix: Set security.oauth2.autoCreateUser: true in settings.yml to automatically provision accounts, or pre-create the user via the admin interface.
Desktop Client Never Returns from Browser
Symptom: When using the Tauri desktop application, the OAuth flow hangs after browser authentication.
Cause: The desktop OAuth callback is not being handled by TauriOAuthUtils.java.
Fix: Ensure the desktop build includes the proprietary security module and that the OAuth redirect uses the custom tauri:// scheme configured in DesktopOAuthButtons.tsx.
Summary
- Enable OAuth2 by setting
security.oauth2.enabled: trueinsettings.ymlto activate the Spring Security OAuth2 flow. - Configure providers under
security.oauth2.clientfor Google, GitHub, or generic OIDC providers like Keycloak usingissuerandproviderfields. - Set redirect URIs to
{baseUrl}/login/oauth2/code/{registrationId}in your identity provider console to match the path defined inOAuth2Configuration.java. - Enable auto-provisioning with
autoCreateUser: trueto allow new users to log in without manual account creation. - Reference implementation files such as
ApplicationProperties.java,OAuth2Configuration.java, andOAuthButtons.tsxwhen debugging or extending functionality.
Frequently Asked Questions
What is the exact redirect URI format for Stirling-PDF OAuth2?
The redirect URI must follow the format {baseUrl}/login/oauth2/code/{registrationId}, where registrationId is the provider name configured in settings.yml (such as google, github, or your custom provider value). This path is defined as OAuth2Configuration.REDIRECT_URI_PATH in the Java source code. You must register this exact URI, including the correct base URL and provider ID, in your identity provider's OAuth2 console to avoid "redirect_uri mismatch" errors.
How do I enable automatic user creation for OAuth2 logins?
Set security.oauth2.autoCreateUser: true in your settings.yml configuration file. When this property is enabled, Stirling-PDF automatically creates a local user account upon first successful OAuth2 authentication, using the attribute specified in useAsUsername (typically email or preferred_username) as the internal username. If disabled, only existing users pre-created in the Stirling-PDF database can authenticate via OAuth2, and new users will be denied access.
Can I use multiple OAuth2 providers simultaneously?
Yes, Stirling-PDF supports concurrent configuration of multiple OAuth2 providers. You can define multiple clients under security.oauth2.client (such as google, github, and a custom keycloak entry) simultaneously. The OAuth2Configuration.java class iterates through all configured providers and registers each as a separate ClientRegistration in the InMemoryClientRegistrationRepository. The frontend component OAuthButtons.tsx dynamically renders a login button for each registered provider, allowing users to choose their preferred authentication method.
Why are the OAuth2 login buttons not appearing in the UI?
The OAuth2 login buttons are rendered by OAuthButtons.tsx only when the backend exposes OAuth2 providers through the API, which requires security.oauth2.enabled: true in settings.yml. If the buttons are missing, first verify that the configuration file is being loaded correctly from the path resolved by InstallationPathConfig.getSettingsPath(). Ensure the YAML syntax is valid and that at least one provider (such as client.google or client.github) is properly configured with valid credentials. If running the desktop Tauri client, ensure you are viewing DesktopOAuthButtons.tsx and that the proprietary security module containing TauriOAuthUtils.java is included in the build.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →