阿里云 Oss 权限控制

前言

最近公司的私有 Oss 服务满了,且 Oss 地址需要设置权限,只有当前系统的登录用户才能访问 Oss 下载地址。一开始想着用 Nginx 做个转发来着,Nginx 每当检测当前请求包含特定的 Oss 地址就转发到我们的统一鉴权接口上去,但是紧接着又细想了一下,转发后的地址被恶意分享出去了,不也还是存在文件泄露的风险吗?于是又去翻阅了一下阿里云的 Oss 权限相关的文档。借此整合一些常用的方法,机械代码自留也是分享给大家

完整代码

里面整合了文件的增、删、修改权限、获取签名等方法,各位替换成各自的 ak、sk 即可

javascript 复制代码
package com.queyi.qykgjx.util;

import com.aliyun.oss.*;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.*;
import org.apache.http.ParseException;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


public class OssUtilCsdn {
    private final static String ENDPOINT = "端点";
    private final static String ACCESS_KEY_ID = "ak";
    private final static String ACCESS_KEY_SECRET = "sk";
    private final static String BUCKET_NAME = "容器名";
    private static String HTTPS_URL_PREFIX = ENDPOINT.replace("https://", ("https://" + BUCKET_NAME + "."));
    private final static String FILE_CATALOG = "文件上传目录";
    
    public static void cpoy(String sourceKey, String dstKey, Boolean deleteSourceFile) {
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        CopyObjectRequest copyObjectRequest = new CopyObjectRequest(BUCKET_NAME, sourceKey, BUCKET_NAME, dstKey);
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setObjectAcl(CannedAccessControlList.Private);
        copyObjectRequest.setNewObjectMetadata(objectMetadata);
        ossClient.copyObject(copyObjectRequest);
        //删除被拷贝的文件
        if (deleteSourceFile) ossClient.deleteObject(BUCKET_NAME, sourceKey);
        ossClient.shutdown();
    }

    public static void setAcl(String bucketName, String url, Boolean privateAcl) {
        ClientBuilderConfiguration config = new ClientBuilderConfiguration();
        config.setSupportCname(false);
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        try {
            ossClient.setObjectAcl(bucketName == null ? BUCKET_NAME : bucketName,
                    getObjectNameByFullUrl(url),
                    privateAcl ? CannedAccessControlList.Private : CannedAccessControlList.PublicRead);
        } catch (OSSException oe) {
            oe.printStackTrace();
        } catch (ClientException ce) {
            ce.printStackTrace();
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    /**
     * @param bucketName 容器名称
     * @param file       待上传的文件
     * @param acl        文件权限
     */
    public static String upload(String bucketName, MultipartFile file, String acl) throws IOException {
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        if (null == bucketName || bucketName.length() > 0) bucketName = BUCKET_NAME;
        InputStream inputStream = file.getInputStream();
        String filename = file.getOriginalFilename();
        String[] split = filename.split("\\.");
        filename = new Date().getTime() + "." + split[split.length - 1];
        String s = FILE_CATALOG + "/" + filename.replaceAll("/", "");
        PutObjectRequest o = new PutObjectRequest(bucketName, s, inputStream);
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        if ("private".equals(acl)) metadata.setObjectAcl(CannedAccessControlList.Private);
        else if ("public".equals(acl)) metadata.setObjectAcl(CannedAccessControlList.PublicRead);
        else metadata.setObjectAcl(CannedAccessControlList.Private);
        o.setMetadata(metadata);
        ossClient.putObject(o);
        ossClient.shutdown();
        inputStream.close();
        return HTTPS_URL_PREFIX + "/" + s;
    }

    /**
     * 获取签名
     */
    public static String getSign(String key, int timeOut) throws ParseException {
        ClientBuilderConfiguration config = new ClientBuilderConfiguration();
        config.setSupportCname(false);
        Date expiration = new Date(new Date().getTime() + timeOut * 1000L);
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET, config);
        URL url = ossClient.generatePresignedUrl(BUCKET_NAME, key, expiration);
        return url.toString().split("\\?")[1];
    }

    public static String getAclPath(String url, int timeOut) throws ParseException {
        ClientBuilderConfiguration config = new ClientBuilderConfiguration();
        config.setSupportCname(false);
        Date expiration = new Date(new Date().getTime() + timeOut * 1000L);
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET, config);
        return ossClient.generatePresignedUrl(BUCKET_NAME, getObjectNameByFullUrl(url), expiration).toString();
    }

    public static String getObjectNameByFullUrl(String url) {
        if (!url.contains(FILE_CATALOG)) return null;
        /**
         * a/a.pdf
         */
        return FILE_CATALOG + url.split(FILE_CATALOG)[1];
    }

    /**
     * 删
     */
    public static List<String> deleteObject(String bucketName, List<String> keys) {
        ArrayList<String> newKeys = new ArrayList<>();
        keys.stream().forEach(key -> {
            newKeys.add(key.replace(HTTPS_URL_PREFIX + "/", ""));
        });
        OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        DeleteObjectsResult deleteObjectsResult = ossClient
                .deleteObjects(new DeleteObjectsRequest(bucketName == null ? BUCKET_NAME : bucketName)
                        .withKeys(newKeys));
        List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
        ossClient.shutdown();
        return deletedObjects;
    }

}

整合接口

javascript 复制代码
 @PostMapping("csdnUpFile")
    public Result csdnUpFile(@RequestParam("file") MultipartFile multipartFile
            , @RequestParam("acl") String perm) throws IOException {
        HashMap<String, String> map = new HashMap<>();
        map.put("fileName", multipartFile.getOriginalFilename());
        map.put("fileUrl", OssUtil.zzhUpload(null, multipartFile, perm));
        return Result.success(map);
    }
    @PostMapping("csdnSetAcl")
    public Result csdnSetAcl(@RequestParam("filePath") String filePath) throws IOException {
        OssUtil.setAcl(null, filePath, true);
        return Result.success("ok");
    }
    @PostMapping("csdnGetAclPath")
    public Result csdnGetAclPath(@RequestParam("filePath") String url) throws IOException {
        return Result.success(OssUtil.getAclPath(url, 60));
    }

    @PostMapping("csdnDeleteFile")
    public Result csdnDeleteDile(@RequestBody List<String> urls) throws IOException {
        return Result.success(OssUtil.deleteObject(null, urls));
    }

测试

上传文件设置成公共读

文件正常访问

将全路径地址作为参数掉修改权限接口

再次访问此地址提示无权限

加上签名访问文件可以正常访问

其他方法不做一一测试了,删除文件也是传上传接口返回的全路径即可,可直接删除文件。其他操作看下阿里的Oss 文档即可,机械代码不做过多描述

相关推荐
非优秀程序员8 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻9 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
文丑颜不良啊11 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang12 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪12 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息13 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼13 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff14 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff15 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc
SL_staff16 小时前
JVS数字底座实践:构建企业级统一内容管理平台的技术路径
java·产品