Skip to content

fix(oauth2): support absolute URLs for authorize_url and token_url#119

Open
ye4241 wants to merge 3 commits into
YFGaia:mainfrom
ye4241:fix/oauth2-support-absolute-urls
Open

fix(oauth2): support absolute URLs for authorize_url and token_url#119
ye4241 wants to merge 3 commits into
YFGaia:mainfrom
ye4241:fix/oauth2-support-absolute-urls

Conversation

@ye4241

@ye4241 ye4241 commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

问题描述

部分 IdP 提供商(例如阿里云 IDaaS)的授权端点(authorization_endpoint)与令牌端点(token_endpoint)位于不同域名下,无法通过单一的 server_url 基地址拼接得到正确的 URL。

原有代码中 authorize_urltoken_url 均被无条件拼接到 server_url 之后:

// login_options.go
baseURLStr := strings.TrimSuffix(configMap.ServerURL, "/") + configMap.AuthorizeURL

// system.go
req, err = http.NewRequest("POST", fmt.Sprintf("%s%s", configMap.ServerURL, configMap.TokenURL), ...)

当用户在界面中填入完整 URL 时,拼接结果会产生形如 https://a.com/https://b.com/token 的无效路径,导致请求失败(HTTP 500)。同时,server_url 被列为必填项,使得纯粹依赖绝对 URL 的配置方式完全无法使用。

修复方案

login_options.go

  • AuthorizeURLhttp 开头时,直接使用该值,不再拼接 ServerURL
  • 移除 ServerURL == "" 的前置校验,允许不填 server_url

system.goTestOAuth2Connection

  • TokenURLhttp 开头时,直接使用该值,不再拼接 ServerURL
  • 同样移除 ServerURL == "" 的前置校验。

兼容性

完全向后兼容。authorize_url / token_url 填写相对路径的已有配置行为不变;填写绝对 URL 的配置新增支持。

测试

已在阿里云 IDaaS(OIDC)环境中验证:

  • authorize_url = https://xxx.aliyunidaas.com/oauth2/authorize(与 server_url 不同域)
  • token_url = https://eiam-api-cn-hangzhou.aliyuncs.com/v2/.../token(与 server_url 不同域)
  • OAuth2 登录及「测试连接」均正常。

Some IdP providers (e.g. Alibaba Cloud IDaaS) expose authorization and
token endpoints on different domains, making it impossible to construct
them from a single server_url base.  The previous code unconditionally
concatenated server_url + authorize_url / token_url, which breaks when
either value is already a fully-qualified URL.

Changes:
- login_options.go: when AuthorizeURL starts with "http", use it
  directly instead of prepending ServerURL.  Remove the ServerURL == ""
  validation guard so that configurations without a server_url are
  accepted.
- system.go (TestOAuth2Connection): same treatment for TokenURL —
  use it as-is when it is an absolute URL.  Remove the ServerURL == ""
  validation guard accordingly.

This is fully backward-compatible: existing configs that store a
relative path in authorize_url / token_url continue to work unchanged.
Copilot AI review requested due to automatic review settings April 23, 2026 09:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Gaia OAuth2 integration to support absolute authorize_url and token_url values (so IdPs with endpoints on different domains don’t break when concatenated with server_url).

Changes:

  • Allow authorize_url to be used as-is when it is an absolute URL (no longer always concatenated with server_url).
  • Allow token_url to be used as-is when it is an absolute URL in TestOAuth2Connection.
  • Remove server_url “required” checks in the two updated call sites.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
admin/server/service/gaia/login_options.go Builds OAuth2 authorization URL; now supports absolute authorize_url without server_url.
admin/server/service/gaia/system.go OAuth2 “test connection” token exchange; now supports absolute token_url without server_url.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread admin/server/service/gaia/system.go Outdated
req, err = http.NewRequest("POST", fmt.Sprintf(
"%s%s", configMap.ServerURL, configMap.TokenURL), strings.NewReader(formData.Encode()))
tokenEndpoint := configMap.TokenURL
if !strings.HasPrefix(tokenEndpoint, "http") {
Comment on lines +51 to +56
var baseURLStr string
if strings.HasPrefix(configMap.AuthorizeURL, "http") {
baseURLStr = configMap.AuthorizeURL
} else {
baseURLStr = strings.TrimSuffix(configMap.ServerURL, "/") + configMap.AuthorizeURL
}
// Extend: 兼容 Casdoor 等 provider。用 net/url 解析并合并 query,保证 client_id 等参数一定被附加上去
baseURLStr := strings.TrimSuffix(configMap.ServerURL, "/") + configMap.AuthorizeURL
var baseURLStr string
if strings.HasPrefix(configMap.AuthorizeURL, "http") {
Comment on lines +37 to 38
if configMap.AuthorizeURL == "" {
return res
Comment thread admin/server/service/gaia/system.go Outdated
Comment on lines +559 to +562
tokenEndpoint := configMap.TokenURL
if !strings.HasPrefix(tokenEndpoint, "http") {
tokenEndpoint = configMap.ServerURL + tokenEndpoint
}
Comment thread admin/server/service/gaia/system.go Outdated
Comment on lines +559 to +563
tokenEndpoint := configMap.TokenURL
if !strings.HasPrefix(tokenEndpoint, "http") {
tokenEndpoint = configMap.ServerURL + tokenEndpoint
}
req, err = http.NewRequest("POST", tokenEndpoint, strings.NewReader(formData.Encode()))
ye4241 added 2 commits April 23, 2026 17:57
…nt from frontend

Two follow-up fixes to the OAuth2 absolute URL support:

1. login_options.go: fix wrong default redirect_uri
   The fallback when redirect_uri is not configured was using
   "/#/loginCallback?provider=oauth2" (a frontend hash route used by
   DingTalk). OAuth2 flow uses the server-side callback handler, so the
   correct default is "/api/base/auth2/callback".

2. admin/web oauth2/index.vue: remove server_url from isConfigValid
   The enable toggle was disabled whenever server_url was empty, which
   made it impossible to save a config that uses absolute URLs for
   authorize_url/token_url without a server_url base. Removing server_url
   from the validation guard matches the backend behavior introduced in
   the previous commit.
- Extract resolveEndpointURL() helper to correctly detect only http:// and
  https:// schemes (vs the too-broad HasPrefix("http") check)
- Return error early when authorize_url/token_url is relative but server_url
  is empty, preventing partial/invalid URL generation
- Apply absolute-URL support to OAuth2CodeLogin token + userinfo endpoints
  (gaia_login.go) to fix "test passes but real login fails" scenario
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants