You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot项目如何通过代码端管控华为云存储媒体的CDN访问权限

解决方案:SpringBoot代码端阻止未授权访问华为云CDN媒体资源

核心思路是不直接暴露永久有效的CDN地址,通过代码层做权限校验后,提供临时可访问路径或代理资源,具体方案如下:

方案1:生成带签名的临时CDN访问地址

华为云CDN支持URL签名鉴权,你可以在代码中完成权限校验后,生成带有效期的签名URL返回给前端,未授权用户拿到过期或无签名的地址无法访问。

实现步骤:

  1. 权限校验:用户请求资源时,先校验登录态、角色或资源归属(比如通过Token判断用户是否有权限查看该媒体)。
  2. 生成签名URL:调用自定义工具类,按照华为云CDN签名规则生成带过期时间的URL。
  3. 返回临时地址:把生成的临时URL返回给前端,前端用这个地址请求CDN。

简化代码示例:

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class CdnSignUtils {
    // 华为云CDN配置的密钥,存在application.yml中
    private static final String CDN_SECRET_KEY = "${your.cdn.secret.key}";

    public static String generateSignedUrl(String originalCdnUrl, long expireMinutes) throws Exception {
        URL url = new URL(originalCdnUrl);
        String uri = url.getPath();
        // 计算过期时间(秒级时间戳)
        long expireTime = System.currentTimeMillis() / 1000 + expireMinutes * 60;

        // 构造签名原始串:uri + 过期时间
        String signRaw = uri + expireTime;
        // 用HMAC-SHA256生成签名
        Mac mac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(CDN_SECRET_KEY.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
        mac.init(secretKey);
        byte[] signBytes = mac.doFinal(signRaw.getBytes(StandardCharsets.UTF_8));
        String signature = Base64.getUrlEncoder().encodeToString(signBytes);

        // 拼接带签名的URL
        return originalCdnUrl + "?sign=" + signature + "&expire=" + expireTime;
    }
}

注意:

  • 密钥不要硬编码,通过SpringBoot配置文件注入;
  • 过期时间根据业务调整(比如5分钟、1小时),平衡安全性和用户体验。

方案2:SpringBoot代理资源请求

前端不直接请求CDN,而是请求你的SpringBoot接口,接口先做权限校验,通过后再从CDN拉取资源返回给前端,完全隐藏CDN地址。

实现步骤:

  1. 接口定义:写一个资源获取接口,接收资源ID或标识;
  2. 权限校验:验证用户是否有权访问该资源;
  3. 代理请求:后端请求华为云CDN获取资源流,直接输出到前端响应。

简化代码示例:

import org.springframework.http.HttpStatus;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@RestController
public class MediaController {

    @GetMapping("/media/{resourceId}")
    public void getMedia(@PathVariable String resourceId, HttpServletResponse response) throws IOException {
        // 1. 权限校验:自定义逻辑判断用户是否有权访问该资源
        if (!checkUserPermission(resourceId)) {
            response.setStatus(HttpStatus.FORBIDDEN.value());
            return;
        }

        // 2. 根据resourceId从数据库/配置中获取原始CDN地址
        String cdnUrl = getCdnUrlByResourceId(resourceId);

        // 3. 拉取CDN资源并返回给前端
        RestTemplate restTemplate = new RestTemplate();
        var resourceResponse = restTemplate.getForEntity(cdnUrl, org.springframework.core.io.Resource.class);

        // 设置响应头,保持资源原始类型
        response.setContentType(resourceResponse.getHeaders().getContentType().toString());
        // 流式传输,避免大文件内存溢出
        StreamUtils.copy(resourceResponse.getBody().getInputStream(), response.getOutputStream());
    }

    // 自定义权限校验方法
    private boolean checkUserPermission(String resourceId) {
        // 示例:校验用户Token、资源归属等
        return true;
    }

    // 自定义方法:根据资源ID获取CDN地址
    private String getCdnUrlByResourceId(String resourceId) {
        // 示例:从数据库查询或配置中读取
        return "https://your-cdn-domain.com/" + resourceId;
    }
}

注意:

  • 大文件场景推荐用流式传输,避免OOM;
  • 可添加缓存逻辑,减少重复请求CDN的开销。

方案3:CDN回源鉴权(结合代码层校验)

配置华为云CDN回源到你的SpringBoot服务,当用户访问CDN地址时,CDN会先回源到你的服务做权限校验,通过后才返回资源。

实现步骤:

  1. CDN配置:在华为云CDN控制台设置回源规则,将资源请求回源到你的SpringBoot服务地址;
  2. 拦截器/过滤器:在SpringBoot中编写拦截器,拦截CDN的回源请求,校验用户身份(比如Cookie、Token);
  3. 权限判断:校验通过则放行,让CDN缓存资源;不通过返回403。

注意:

  • 要识别CDN回源请求的标识头(比如华为云CDN的X-Cdn-Source),避免拦截普通用户请求;
  • 确保回源请求的安全性,防止伪造回源请求。

方案选择建议

  • 优先选方案1:实现简单、性能开销小,适合大多数场景;
  • 需要实时校验权限或完全隐藏CDN地址,选方案2;
  • 需统一管控所有CDN资源访问,选方案3。

内容的提问来源于stack exchange,提问作者dempsey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:30:15