Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions admin/server/service/gaia/gaia_login.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ func (e *SystemIntegratedService) OAuth2CodeLogin(
formData.Set("client_id", integrate.AppID)
formData.Set("client_secret", integrate.AppSecret)
}
tokenURL := strings.TrimSuffix(configMap.ServerURL, "/") + configMap.TokenURL
tokenURL, err := resolveEndpointURL(configMap.ServerURL, configMap.TokenURL)
if err != nil {
return nil, fmt.Errorf("token_url 配置错误: %w", err)
}
httpReq, err := http.NewRequest("POST", tokenURL, strings.NewReader(formData.Encode()))
if err != nil {
return nil, err
Expand Down Expand Up @@ -97,7 +100,10 @@ func (e *SystemIntegratedService) OAuth2CodeLogin(
// Extend Stop: 兼容 casdoor

// 拉用户信息
userInfoURL := strings.TrimSuffix(configMap.ServerURL, "/") + configMap.UserinfoURL
userInfoURL, err := resolveEndpointURL(configMap.ServerURL, configMap.UserinfoURL)
if err != nil {
return nil, fmt.Errorf("userinfo_url 配置错误: %w", err)
}
userReq, err := http.NewRequest("GET", userInfoURL, nil)
if err != nil {
return nil, err
Expand Down
28 changes: 25 additions & 3 deletions admin/server/service/gaia/login_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ import (
"strings"
)

// isAbsoluteHTTP returns true only for URLs starting with "http://" or "https://".
func isAbsoluteHTTP(s string) bool {
return strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")
}

// resolveEndpointURL returns an absolute endpoint URL.
// If endpointURL is absolute (http:// or https://), it is returned as-is.
// Otherwise serverURL is prepended with trailing-slash normalization.
// Returns an error if endpointURL is relative and serverURL is empty.
func resolveEndpointURL(serverURL, endpointURL string) (string, error) {
if isAbsoluteHTTP(endpointURL) {
return endpointURL, nil
}
if strings.TrimSpace(serverURL) == "" {
return "", fmt.Errorf("server_url 未配置,且端点 %q 不是绝对 URL", endpointURL)
}
return strings.TrimSuffix(serverURL, "/") + endpointURL, nil
}

// GetLoginOptions 获取登录方式选项(供登录页展示钉钉/OAuth2 按钮,不暴露密钥)
func (e *SystemIntegratedService) GetLoginOptions(frontendOrigin string) (res response.LoginOptionsResponse) {
// 非本地的需要加上 admin(若 Referer 已带 /admin 则不再追加,避免 /admin/admin)
Expand All @@ -34,21 +53,24 @@ func (e *SystemIntegratedService) GetLoginOptions(frontendOrigin string) (res re
if err := json.Unmarshal([]byte(integrateOAuth.Config), &configMap); err != nil {
return res
}
if configMap.ServerURL == "" || configMap.AuthorizeURL == "" {
if configMap.AuthorizeURL == "" {
return res
Comment on lines +56 to 57
}
res.OAuth2.Enabled = true
redirectURI := strings.TrimSpace(configMap.RedirectUri)
if redirectURI == "" {
redirectURI = frontendOrigin + "/#/loginCallback?provider=oauth2"
redirectURI = frontendOrigin + "/api/base/auth2/callback"
}
res.OAuth2.RedirectURI = redirectURI
scope := strings.TrimSpace(configMap.Scope)
if scope == "" {
scope = "openid"
}
// Extend: 兼容 Casdoor 等 provider。用 net/url 解析并合并 query,保证 client_id 等参数一定被附加上去
baseURLStr := strings.TrimSuffix(configMap.ServerURL, "/") + configMap.AuthorizeURL
baseURLStr, err := resolveEndpointURL(configMap.ServerURL, configMap.AuthorizeURL)
if err != nil {
return res
}
u, err := url.Parse(baseURLStr)
if err != nil {
// 解析失败时退回字符串拼接
Expand Down
9 changes: 6 additions & 3 deletions admin/server/service/gaia/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ func (e *SystemIntegratedService) TestOAuth2Connection(integrate gaia.SystemInte
return nil
}
// 检查必要字段
if configMap.ServerURL == "" || configMap.TokenURL == "" || integrate.AppID == "" || integrate.AppSecret == "" {
if configMap.TokenURL == "" || integrate.AppID == "" || integrate.AppSecret == "" {
return errors.New("请填写完整的 OAuth2 配置信息")
}

Expand All @@ -556,8 +556,11 @@ func (e *SystemIntegratedService) TestOAuth2Connection(integrate gaia.SystemInte
// 发送请求
var req *http.Request
client := &http.Client{}
req, err = http.NewRequest("POST", fmt.Sprintf(
"%s%s", configMap.ServerURL, configMap.TokenURL), strings.NewReader(formData.Encode()))
tokenEndpoint, err := resolveEndpointURL(configMap.ServerURL, configMap.TokenURL)
if err != nil {
return errors.New(fmt.Sprintf("token_url 配置错误: %s", err.Error()))
}
req, err = http.NewRequest("POST", tokenEndpoint, strings.NewReader(formData.Encode()))
if err != nil {
global.GVA_LOG.Error("创建测试请求失败", zap.Error(err))
return errors.New(fmt.Sprintf("创建测试请求失败: %s", err.Error()))
Expand Down
3 changes: 1 addition & 2 deletions admin/web/src/view/systemIntegrated/oauth2/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,9 @@ const config = ref({
test: false,
})

// 验证配置是否有效
// 验证配置是否有效(server_url 为可选,支持 token_url/authorize_url 填绝对 URL 的场景)
const isConfigValid = computed(() => {
return !!(
config.value.server_url &&
config.value.token_url &&
config.value.userinfo_url &&
config.value.app_id &&
Expand Down
Loading