OAuth 2.0 Single Sign-On Configuration
Tier: Server
Stirling PDF supports Single Sign-On (SSO) using OAuth 2.0 OpenID Connect (OIDC). This allows users to log in using accounts from external providers such as Google, GitHub, Keycloak, Authentik, and others.
Looking for SAML 2.0 SSO? See SAML SSO Configuration (Enterprise tier).
Prerequisites#
Before configuring OAuth 2.0 SSO, ensure you have:
- [ ] Stirling PDF with login enabled (
security.enableLogin: true) - [ ] Valid license for the Server tier or higher
- [ ] An OAuth 2.0 provider account (Google, GitHub, Keycloak, etc.)
- [ ] Registered OAuth application with your provider
- [ ] OAuth Client ID and Client Secret from your provider
- [ ] Public HTTPS URL configured with
system.backendUrlset to your public backend API URL (often same as frontend, verifyhttps://your-domain.com/api/v1/info/statusis accessible) - [ ] Callback URL added to provider:
https://your-domain.com/login/oauth2/code/<provider>
Tip: Start with
loginMethod: allduring initial setup to allow both username/password and OAuth login. This ensures you can always access the admin account if SSO configuration needs adjustment.
Setup Guide#
Step 1: Configure Login Settings#
Enable login and set the login method to allow both standard and OAuth authentication during initial setup.
security:
enableLogin: true
loginMethod: all # Allows both username/password and OAuth loginSECURITY_ENABLELOGIN=true
SECURITY_LOGINMETHOD=allLogin Method Options:
all: Enables all login methods (username/password + OAuth 2)normal: Username/password onlyoauth2: OAuth 2 SSO only (disables username/password login)saml2: SAML 2 SSO only (Enterprise tier)
Step 2: Create Initial Admin Account#
Before enabling OAuth, create an initial admin account using one of these methods:
Option A: Use initialLogin credentials (recommended for first setup)
security:
initialLogin:
username: 'admin'
password: 'yourSecurePassword123'SECURITY_INITIALLOGIN_USERNAME=admin
SECURITY_INITIALLOGIN_PASSWORD=yourSecurePassword123Option B: Create admin manually
- Access Stirling PDF with OAuth disabled
- Create an admin user through the UI
- Then enable OAuth
Step 3: Configure OAuth Provider#
Set security.oauth2.enabled to true and configure your chosen provider.
security:
oauth2:
enabled: true
client:
google:
clientId: <YOUR_CLIENT_ID>
clientSecret: <YOUR_CLIENT_SECRET>
scopes: email, profile
useAsUsername: email
provider: google
autoCreateUser: true
blockRegistration: falseSECURITY_OAUTH2_ENABLED=true
SECURITY_OAUTH2_CLIENT_GOOGLE_CLIENTID=<YOUR_CLIENT_ID>
SECURITY_OAUTH2_CLIENT_GOOGLE_CLIENTSECRET=<YOUR_CLIENT_SECRET>
SECURITY_OAUTH2_CLIENT_GOOGLE_SCOPES=email, profile
SECURITY_OAUTH2_CLIENT_GOOGLE_USEASUSERNAME=email
SECURITY_OAUTH2_PROVIDER=google
SECURITY_OAUTH2_AUTOCREATEUSER=true
SECURITY_OAUTH2_BLOCKREGISTRATION=falseProvider Setup:
- Go to Google Cloud Console
- Create a new project or select existing
- Enable Google+ API
- Create OAuth 2.0 credentials (Web application)
- Add authorized redirect URI:
https://your-domain.com/login/oauth2/code/google - Copy Client ID and Client Secret
security:
oauth2:
enabled: true
client:
github:
clientId: <YOUR_CLIENT_ID>
clientSecret: <YOUR_CLIENT_SECRET>
scopes: read:user
useAsUsername: login
provider: github
autoCreateUser: true
blockRegistration: falseSECURITY_OAUTH2_ENABLED=true
SECURITY_OAUTH2_CLIENT_GITHUB_CLIENTID=<YOUR_CLIENT_ID>
SECURITY_OAUTH2_CLIENT_GITHUB_CLIENTSECRET=<YOUR_CLIENT_SECRET>
SECURITY_OAUTH2_CLIENT_GITHUB_SCOPES=read:user
SECURITY_OAUTH2_CLIENT_GITHUB_USEASUSERNAME=login
SECURITY_OAUTH2_PROVIDER=github
SECURITY_OAUTH2_AUTOCREATEUSER=true
SECURITY_OAUTH2_BLOCKREGISTRATION=falseProvider Setup:
- Go to GitHub Developer Settings
- Create new OAuth App
- Set Authorization callback URL:
https://your-domain.com/login/oauth2/code/github - Copy Client ID and generate Client Secret
security:
oauth2:
enabled: true
issuer: https://your-keycloak.com/realms/your-realm
clientId: <YOUR_CLIENT_ID>
clientSecret: <YOUR_CLIENT_SECRET>
scopes: openid, profile, email
useAsUsername: preferred_username
provider: keycloak
autoCreateUser: true
blockRegistration: falseSECURITY_OAUTH2_ENABLED=true
SECURITY_OAUTH2_ISSUER=https://your-keycloak.com/realms/your-realm
SECURITY_OAUTH2_CLIENTID=<YOUR_CLIENT_ID>
SECURITY_OAUTH2_CLIENTSECRET=<YOUR_CLIENT_SECRET>
SECURITY_OAUTH2_SCOPES=openid, profile, email
SECURITY_OAUTH2_USEASUSERNAME=preferred_username
SECURITY_OAUTH2_PROVIDER=keycloak
SECURITY_OAUTH2_AUTOCREATEUSER=true
SECURITY_OAUTH2_BLOCKREGISTRATION=falseProvider Setup:
- Access your Keycloak admin console
- Select your realm
- Create new client (OpenID Connect)
- Set Valid Redirect URIs:
https://your-domain.com/login/oauth2/code/keycloak - Enable "Client authentication" for confidential access
- Copy Client ID and Client Secret from Credentials tab
security:
oauth2:
enabled: true
issuer: https://your-authentik.com/application/o/stirling-pdf/
clientId: <YOUR_CLIENT_ID>
clientSecret: <YOUR_CLIENT_SECRET>
scopes: openid, profile, email
useAsUsername: preferred_username
provider: authentik
autoCreateUser: true
blockRegistration: falseSECURITY_OAUTH2_ENABLED=true
SECURITY_OAUTH2_ISSUER=https://your-authentik.com/application/o/stirling-pdf/
SECURITY_OAUTH2_CLIENTID=<YOUR_CLIENT_ID>
SECURITY_OAUTH2_CLIENTSECRET=<YOUR_CLIENT_SECRET>
SECURITY_OAUTH2_SCOPES=openid, profile, email
SECURITY_OAUTH2_USEASUSERNAME=preferred_username
SECURITY_OAUTH2_PROVIDER=authentik
SECURITY_OAUTH2_AUTOCREATEUSER=true
SECURITY_OAUTH2_BLOCKREGISTRATION=falseProvider Setup:
- Create new Provider (OAuth2/OpenID)
- Create new Application
- Set Redirect URIs:
https://your-domain.com/login/oauth2/code/authentik - Copy Client ID and Client Secret
security:
oauth2:
enabled: true
issuer: <YOUR_ISSUER_URI>
clientId: <YOUR_CLIENT_ID>
clientSecret: <YOUR_CLIENT_SECRET>
scopes: openid, profile, email
useAsUsername: email
provider: <PROVIDER_NAME>
autoCreateUser: true
blockRegistration: falseSECURITY_OAUTH2_ENABLED=true
SECURITY_OAUTH2_ISSUER=<YOUR_ISSUER_URI>
SECURITY_OAUTH2_CLIENTID=<YOUR_CLIENT_ID>
SECURITY_OAUTH2_CLIENTSECRET=<YOUR_CLIENT_SECRET>
SECURITY_OAUTH2_SCOPES=openid, profile, email
SECURITY_OAUTH2_USEASUSERNAME=email
SECURITY_OAUTH2_PROVIDER=<PROVIDER_NAME>
SECURITY_OAUTH2_AUTOCREATEUSER=true
SECURITY_OAUTH2_BLOCKREGISTRATION=falseRequirements:
- Provider must support OpenID Connect Discovery
- Must expose
/.well-known/openid-configurationendpoint
Step 4: Configure Callback URL#
When registering your application with the OAuth provider, use this callback URL format:
https://<your-domain>/login/oauth2/code/<provider>Understanding the Provider Slug:
The <provider> portion of the callback URL must exactly match your security.oauth2.provider configuration value:
security:
oauth2:
provider: authentik # This becomes part of the callback URLWith the above configuration, your callback URL becomes:
https://your-domain.com/login/oauth2/code/authentikExamples:
- Google:
https://stirling.example.com/login/oauth2/code/google - GitHub:
https://stirling.example.com/login/oauth2/code/github - Keycloak:
https://stirling.example.com/login/oauth2/code/keycloak - Custom provider:
https://stirling.example.com/login/oauth2/code/mycompany
Important: If the provider slug in the callback URL doesn't match your
security.oauth2.providervalue, OAuth login will fail with redirect errors.
Tip: For generic OIDC providers (not Google/GitHub/Keycloak), you can set
providerto any lowercase alphanumeric value that makes sense for your organization.
Step 5: Test OAuth Login and Promote User#
- Restart Stirling PDF
- Test OAuth login in an incognito/private browser window
- Verify you can log in with your OAuth provider
- Log in with your initial admin account (username/password)
- Go to Settings → User Management
- Find the OAuth user account (created during test login)
- Change role to Admin
Step 6: (Optional) Switch to SSO-Only Mode#
Once you've verified OAuth works and promoted an OAuth user to admin, you can disable username/password login:
security:
loginMethod: oauth2 # Disables username/password loginSECURITY_LOGINMETHOD=oauth2Important: If you set
loginMethod: oauth2before creating an OAuth admin user, you will only be able to log in via OAuth, and all new OAuth users will have regular user permissions. KeeploginMethod: alluntil you have at least one OAuth user with admin privileges.
Configuration Reference#
Required Properties#
| Property | Description | Example |
|---|---|---|
security.oauth2.enabled |
Enable OAuth 2 login | true |
security.oauth2.clientId |
Client ID from your OAuth provider | stirling-pdf-client |
security.oauth2.clientSecret |
Client Secret from your OAuth provider | your-secret-key |
security.oauth2.provider |
Provider name | google, github, keycloak, authentik |
Optional Properties#
| Property | Description | Default | Example |
|---|---|---|---|
security.oauth2.issuer |
OIDC issuer URL (required for generic providers, must support /.well-known/openid-configuration) |
- | https://keycloak.example.com/realms/myrealm |
security.oauth2.autoCreateUser |
Auto-create users on first login | true |
false |
security.oauth2.blockRegistration |
Block new user registration, only allow pre-registered users | false |
true |
security.oauth2.scopes |
Space or comma-separated list of OAuth scopes | Provider-specific | openid, profile, email |
security.oauth2.useAsUsername |
Claim to use as username (options depend on provider) | Provider-specific | email, preferred_username, login |
Provider-Specific Configuration#
Named providers (Google, GitHub, Keycloak):
oauth2:
client:
google: # or github, keycloak
clientId: ...
clientSecret: ...Generic providers (Authentik, custom OIDC):
oauth2:
issuer: <ISSUER_URI> # Must support OIDC discovery
clientId: ...
clientSecret: ...Username Claim Options#
Google:
email,name,given_name,family_name- See Google OAuth Scopes
GitHub:
login,email,name- See GitHub OAuth Scopes
Keycloak/Generic OIDC:
email,preferred_username,nickname,name
Advanced Configuration#
Backend URL Configuration#
If your Stirling PDF backend is accessible at a different URL than the frontend, configure the backend URL:
system:
backendUrl: https://stirling-api.example.comSYSTEM_BACKENDURL=https://stirling-api.example.comVerify the backend URL is correct by checking that https://your-domain.com/api/v1/info/status is accessible.
Auto-Login Feature#
Tier: Server
Automatically redirect users to OAuth login page, bypassing the Stirling PDF login screen.
premium:
proFeatures:
ssoAutoLogin: truePREMIUM_PROFEATURES_SSOAUTOLOGIN=trueAuto-login Activation Requirements:
Auto-login only triggers when ALL of the following conditions are met:
ssoAutoLoginis enabled (as configured above)loginMethodis NOT'all'and NOT'normal'(i.e., SSO-only mode required)- Exactly one OAuth provider is configured
Behavior:
- When all conditions are met: Users are automatically redirected to OAuth provider login
- When conditions are not met: Standard login page is displayed
- If the SSO redirect fails, the browser stops auto-redirecting for the current session so the login page stays reachable
- After logging out, auto-redirect is suppressed for that session so you can sign in as a different user
User Interface#
Once OAuth is configured, users will see the SSO login button:
![]() |
![]() |
|---|
Troubleshooting#
Common Issues#
"OAuth2 authentication error"
- Verify callback URL matches exactly (including provider slug)
- Check client ID and secret are correct
- Ensure provider allows the configured redirect URI
- Confirm
security.oauth2.providermatches the provider slug in callback URL
"Invalid issuer"
- Confirm issuer URL is correct
- Test
https://your-issuer/.well-known/openid-configurationreturns valid JSON - Check network connectivity from Stirling PDF container to provider
"User not created"
- Set
autoCreateUser: true - Check
blockRegistrationisfalseor user is pre-registered - Verify license allows user count
Users redirected to wrong URL
- Verify
system.backendUrlis configured correctly - Test that
https://your-domain.com/api/v1/info/statusis accessible - Check provider's registered redirect URIs match your domain
Debug Logging#
Enable OAuth debug logging to troubleshoot authentication issues.
logging:
level:
org.springframework.security.oauth2: DEBUGLOGGING_LEVEL_ORG_SPRINGFRAMEWORK_SECURITY_OAUTH2=DEBUGLogging the Provider's Claims ("Attribute value for email cannot be null")#
If login fails with "Attribute value for email cannot be null" (common with ADFS and Azure AD), the provider is not returning the claim named by useAsUsername. Enable security.oauth2.debugLogging to log the full ID-token / UserInfo claim set and the resolved username, so you can see exactly which claims the provider sends and pick the right useAsUsername value.
security:
oauth2:
debugLogging: trueSECURITY_OAUTH2_DEBUGLOGGING=trueThe claims are logged at INFO level on each login (and again at ERROR level when the username attribute cannot be resolved).
⚠️ Disable debugLogging again as soon as you are done. It writes personally identifiable information (such as sub, email, and name) to the application logs.
Known Limitations#
- OAuth users must be manually promoted to admin role after first login
- Provider discovery requires
/.well-known/openid-configurationendpoint support - Auto-login feature requires the Server tier (or higher)
See Also#
- SAML SSO Configuration - Enterprise SAML 2.0 setup
- System and Security - Additional security settings
- External Database - User storage configuration

