Skip to content

OAuth2/OIDC redirect URLs resolved relative to Gitea's own domain instead of the provider's (authorize, logout endpoints) #38315

Description

@andrewstod84

Gitea Version

1.26.4

What happened?

Description:
When configuring an OpenID Connect authentication source (tested against Microsoft Entra ID / Azure AD), Gitea generates redirect URLs for the authorization and end-session (logout) endpoints that are resolved relative to Gitea's own ROOT_URL instead of the provider's actual host. This results in a 404 on Gitea's own router rather than a redirect to the identity provider.

Steps to reproduce:

  1. Configure an OpenID Connect OAuth2 authentication source with Auto Discovery URL set to:
    https://login.microsoftonline.com/{TENANT_ID}/v2.0/.well-known/openid-configuration
  2. Confirm the discovery document itself is valid and returns fully-qualified absolute URLs,
    e.g. authorization_endpoint: https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/authorize
  3. Click "Sign in with {SOURCE_NAME}" on the Gitea login page
  4. Gitea returns a 307 redirect from /user/oauth2/{SOURCE_NAME}, but the Location header contains only the
    path portion of the authorization_endpoint (missing scheme + host), e.g.:
    /{TENANT_ID}/oauth2/v2.0/authorize?client_id={CLIENT_ID}&redirect_uri=https%3A%2F%2F{GITEA_DOMAIN}%2Fuser%2Foauth2%2F{SOURCE_NAME}%2Fcallback&response_type=code&scope=openid&state={STATE}
  5. The browser follows this as relative to Gitea's own domain, resulting in a 404 from Gitea's own router
    (confirmed via gitea.log: "WebNotFound").
  6. Same behavior reproduces for the OIDC logout/end-session endpoint:
    /{TENANT_ID}/oauth2/v2.0/logout?client_id={CLIENT_ID}&post_logout_redirect_uri=https%3A%2F%2F{GITEA_DOMAIN}%2F

Expected behavior:
Gitea should redirect to the fully-qualified authorization_endpoint / end_session_endpoint URL returned
by the OIDC discovery document (i.e., including https://login.microsoftonline.com host), not a
path resolved relative to Gitea's own ROOT_URL.

Gitea version: 1.26.4
Git version: [paste your git --version output]
Operating system: Windows Server 2025
Database: MSSQL (SQL Server 2022)
Reverse proxy: IIS with URL Rewrite / ARR (confirmed not a proxy issue — ROOT_URL is correctly set
and confirmed in gitea.log: "AppURL(ROOT_URL): https://{GITEA_DOMAIN}/"; reproduced identically
hitting Gitea directly on localhost:3000, bypassing the proxy entirely)

Relevant log line:
router: completed GET /{TENANT_ID}/oauth2/v2.0/authorize?... for [CLIENT_IP]:0, 404 Not Found in 17.0ms @ :1(WebNotFound)

Additional notes:

  • Confirmed this is not the same issue fixed in Fix URL related escaping for oauth2 #37334 (URL escaping for oauth2, merged in 1.26.1) —
    this instance is running 1.26.4, well after that fix landed.
  • Both CLI-created (admin auth add-oauth --provider openidConnect) and web-UI-created sources
    reproduce identically.
  • Currently working around this at the reverse proxy layer by intercepting and correcting the
    malformed redirect via URL Rewrite before it reaches Gitea's router.

How are you running Gitea?

Gitea binary (Windows), running as a Windows Service via NSSM, behind an IIS reverse proxy

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions