fix(media): 资源访问 - 签名地址有效期跟随后台策略并放开服务器访问地址限制
平台展示与厂商读取的签名地址有效期改为读取「资源与请求策略」,默认均为 4 小时,不再硬编码 5 分钟。服务器访问地址只校验 http/https 格式,允许本机、局域网或 HTTP 地址,模型读取平台资源不再强制 HTTPS 公网地址。
This commit is contained in:
1 parent
4957f8bc22
commit
4272b0e499
9 files changed
+40
-14
No files matched your search
@@ -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 {
|
||||
|
||||
@@ -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("服务器访问地址不能包含查询参数或片段")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user