# How to Configure OAuth2 Authentication in Stirling-PDF: Enterprise SSO Guide

> Configure OAuth2 authentication in Stirling-PDF for enterprise SSO. Easily enable secure logins by setting security.oauth2.enabled true and configuring your identity provider.

- Repository: [Stirling Tools/Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Enable OAuth2 in Stirling-PDF by setting `security.oauth2.enabled: true` in [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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](https://github.com/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/ApplicationProperties.java)

All OAuth2 settings are loaded from [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) into the `Security.OAUTH2` inner class inside [[`ApplicationProperties.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuth2Configuration.java)

The [[`OAuth2Configuration.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuthButtons.tsx)

The React component [[`OAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) to enable the OAuth2 module and define which user attribute to map as the internal username:

```yaml
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`:

```yaml
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:

```yaml
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:

```yaml
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:

```yaml
security:
  oauth2:
    autoCreateUser: true

```

When `false`, only existing Stirling-PDF users can log in via OAuth2.

### Restart and Verify

1. Restart the application to trigger `OAuth2Configuration.clientRegistrationRepository()` validation
2. 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`)
3. Check that [`OAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuthButtons.tsx) renders buttons linking to `/oauth2/authorization/{registrationId}`

## Complete Configuration Example

```yaml

# 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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/ApplicationProperties.java)** – Defines the `Security.OAUTH2` configuration model that maps [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) properties to Java objects. Located at [`app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/common/src/main/java/stirling/software/common/model/ApplicationProperties.java).

- **[`OAuth2Configuration.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuth2Configuration.java)** – Constructs `ClientRegistration` beans and registers them with Spring Security’s `InMemoryClientRegistrationRepository`. Located at [`app/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/OAuth2Configuration.java).

- **[`OAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuthButtons.tsx)** – React component that renders OAuth provider buttons linking to `/oauth2/authorization/{registrationId}`. Located at [`frontend/src/proprietary/routes/login/OAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/frontend/src/proprietary/routes/login/OAuthButtons.tsx).

- **[`DesktopOAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DesktopOAuthButtons.tsx)** – Desktop-specific OAuth UI for the Tauri client. Located at [`frontend/src/desktop/components/SetupWizard/DesktopOAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/frontend/src/desktop/components/SetupWizard/DesktopOAuthButtons.tsx).

- **[`TauriOAuthUtils.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/TauriOAuthUtils.java)** – Utility class handling OAuth callbacks for the desktop application. Located at [`app/proprietary/src/main/java/stirling/software/proprietary/security/oauth2/TauriOAuthUtils.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/app/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DesktopOAuthButtons.tsx).

## Summary

- **Enable OAuth2** by setting `security.oauth2.enabled: true` in [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/settings.yml) to activate the Spring Security OAuth2 flow.
- **Configure providers** under `security.oauth2.client` for Google, GitHub, or generic OIDC providers like Keycloak using `issuer` and `provider` fields.
- **Set redirect URIs** to `{baseUrl}/login/oauth2/code/{registrationId}` in your identity provider console to match the path defined in [`OAuth2Configuration.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuth2Configuration.java).
- **Enable auto-provisioning** with `autoCreateUser: true` to allow new users to log in without manual account creation.
- **Reference implementation files** such as [`ApplicationProperties.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/ApplicationProperties.java), [`OAuth2Configuration.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuth2Configuration.java), and [`OAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuthButtons.tsx) when 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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuth2Configuration.java) class iterates through all configured providers and registers each as a separate `ClientRegistration` in the `InMemoryClientRegistrationRepository`. The frontend component [`OAuthButtons.tsx`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/OAuthButtons.tsx) only when the backend exposes OAuth2 providers through the API, which requires `security.oauth2.enabled: true` in [`settings.yml`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/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`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DesktopOAuthButtons.tsx) and that the proprietary security module containing [`TauriOAuthUtils.java`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/TauriOAuthUtils.java) is included in the build.