fix(media): 资源访问 - 签名地址有效期跟随后台策略并放开服务器访问地址限制

平台展示与厂商读取的签名地址有效期改为读取「资源与请求策略」,默认均为 4 小时,不再硬编码 5 分钟。服务器访问地址只校验 http/https 格式,允许本机、局域网或 HTTP 地址,模型读取平台资源不再强制 HTTPS 公网地址。
This commit is contained in:
ddcat666 committed 2026-09-30 03:38:31 +08:00
1 parent 4957f8bc22
commit 4272b0e499
9 files changed
+40 -14

No files matched your search

+1 -1
View File
@@ -805,7 +805,7 @@ func (s *Service) hydrateProviderMedia(userID string, media *providerMedia, poli
}
useObjectURL := policy.requireURL || (policy.preferURL && resourceUsesObjectStorage(resource))
if useObjectURL {
signedURL, err := s.providerResourceURL(resource, time.Now().Add(providerResourceURLTTL))
signedURL, err := s.providerResourceURL(resource, time.Time{})
if err != nil {
return fmt.Errorf("生成参考素材地址失败:%w", err)
}
@@ -18,6 +18,7 @@ func (s *Service) ResourceForUser(actor *model.User, id string) (*model.Resource
// providerResourceURL 只能接收已经完成用户归属和 ready 状态校验的资源,
// 并为上游签发短时地址;它不是绕过权限校验的通用资源 URL 生成器。
// expiresAt 为零值时使用后台「厂商访问地址有效期」(默认 4 小时),非零时只能进一步缩短。
func (s *Service) providerResourceURL(resource *model.Resource, expiresAt time.Time) (string, error) {
access, err := s.resolveResourceAccess(resource, ResourceAccessOptions{Purpose: assets.PurposeProvider, ExpiresAt: expiresAt})
if err != nil {
+11 -5
View File
@@ -32,8 +32,6 @@ import (
"gorm.io/gorm"
)
const providerResourceURLTTL = 4 * time.Hour
var errInvalidGeneratedDataURL = errors.New("生成内容 data URL 无效")
type ResourceStream = assets.ResourceStream
@@ -95,10 +93,18 @@ func (s *Service) publicResourceBaseURL() (*url.URL, error) {
return validatePublicResourceBaseURL(raw)
}
// 服务器访问地址是本服务对外暴露的根地址,由管理员自行决定,
// 允许本机、局域网或任意主机;这里只校验格式,不套用出站私网策略。
func validatePublicResourceBaseURL(raw string) (*url.URL, error) {
parsed, err := ValidateOutboundURL(raw)
if err != nil {
return nil, err
parsed, err := url.Parse(strings.TrimSpace(raw))
if err != nil || parsed.Hostname() == "" {
return nil, BadAuthRequest("服务器访问地址必须是完整的 http/https 地址")
}
if parsed.Scheme != "https" && parsed.Scheme != "http" {
return nil, BadAuthRequest("服务器访问地址只支持 http/https")
}
if parsed.User != nil {
return nil, BadAuthRequest("服务器访问地址不能包含认证信息")
}
if parsed.RawQuery != "" || parsed.Fragment != "" {
return nil, BadAuthRequest("服务器访问地址不能包含查询参数或片段")
+4 -3
View File
@@ -70,6 +70,10 @@ func (s *Service) resolveResourceAccess(resource *model.Resource, options Resour
if err != nil {
return nil, WrapAppError(503, "无法解析资源实际存储位置", err)
}
setting = s.storageSettingWithRuntimePolicy(setting)
} else {
// 本地资源无需存储配置,只注入运行时策略,让平台签名地址同样遵循后台配置的有效期。
setting.Runtime = s.storageSettingWithRuntimePolicy(ossSettingValue{}).Runtime
}
return assets.ResolveAccess(resource, setting, options, time.Now().UTC(), func(variant assets.ResourceVariant, expires time.Time) (string, error) {
return s.signedResourceAccessURL(resource, variant, expires, options.Purpose == assets.PurposeProvider)
@@ -134,9 +138,6 @@ func (s *Service) signedResourceAccessURL(resource *model.Resource, variant asse
if err != nil {
return "", err
}
if base.Scheme != "https" {
return "", BadAuthRequest("模型读取平台资源需要配置 HTTPS 公网访问地址")
}
return base.ResolveReference(u).String(), nil
}