阿里云 Oss 权限控制

前言

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

完整代码

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

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;}}

整合接口

 @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 文档即可,机械代码不做过多描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146419.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

picoctf_2018_shellcode

picoctf_2018_shellcode Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments32位&#xff0c;啥都没开 这个看着挺大的&#xff0c;直接来个ROPchain&#xff0c;…

Redis缓存穿透、击穿和雪崩

面试高频 服务的高可用问题&#xff01; 在这里我们不会详细的区分析解决方案的底层&#xff01; Redis缓存概念 Redis缓存的使用&#xff0c;极大的提升了应用程序的性能和效率&#xff0c;特别是数据查询方面。但同时&#xff0c;它也带来了一些问题。其中&#xff0c;最要…

Android stdio的Gradle菜单栏无内容问题的解决方法

右边Gradle菜单栏里没有Tasks选项内容的问题 正常情况↓ 如果这个问题如果无法解决的话&#xff0c;Gradle打包就只能通过控制台输入命令来解决&#xff0c;但这无疑是把简单问题复杂化了&#xff0c;我们来看看怎么解决这个问题吧。 这里有几个方法提供&#xff0c;可以自行选…

排序篇(四)----归并排序

排序篇(四)----归并排序 1.归并(递归) 基本思想&#xff1a; 归并排序&#xff08;MERGE-SORT&#xff09;是建立在归并操作上的一种有效的排序算法,该算法是采用分治法&#xff08;Divide andConquer&#xff09;的一个非常典型的应用。将已有序的子序列合并&#xff0c;得到…

leetCode 376.摆动序列 动态规划 + 图解 + 状态转移

376. 摆动序列 - 力扣&#xff08;LeetCode&#xff09; 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;则数字序列称为 摆动序列 。第一个差&#xff08;如果存在的话&#xff09;可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如…

微信小程序引入字体在部分机型失效不兼容解决办法

写小程序页面&#xff0c;美工作图用了特殊字体 引入代码&#xff1a; font-face {font-family: huxiaobo;src: url("https://xxxxxxxx.top/assets/fonts/huxiaobonanshenti.woff") } .font-loaded {font-family: "huxiaobo"; } 上线后发现部分安卓机型不…

209. 长度最小的子数组(滑动窗口)

一、题目 209. 长度最小的子数组 - 力扣&#xff08;LeetCode&#xff09; 二、代码 class Solution { public:int minSubArrayLen(int target, vector<int>& nums) {int left 0, right 0;int sum nums[right];int MinLength INT_MAX;while (left <nums.siz…

计算机竞赛 深度学习火车票识别系统

文章目录 0 前言1 课题意义课题难点&#xff1a; 2 实现方法2.1 图像预处理2.2 字符分割2.3 字符识别部分实现代码 3 实现效果4 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 图像识别 火车票识别系统 该项目较为新颖&#xff0c;适…

54、数组--模拟

LCR 146. 螺旋遍历二维数组 给定一个二维数组 array&#xff0c;请返回「螺旋遍历」该数组的结果。 螺旋遍历&#xff1a;从左上角开始&#xff0c;按照 向右、向下、向左、向上 的顺序 依次 提取元素&#xff0c;然后再进入内部一层重复相同的步骤&#xff0c;直到提取完所有…

(vue3)create-vue 组合式APIsetup、ref、watch,通信

优势&#xff1a; 更易维护&#xff1a;组合式api&#xff0c;更好的TS支持 之前是选项式api&#xff0c;现在是组合式&#xff0c;把同功能的api集合式管理 复用功能封装成一整个函数 更快的速度 更小的体积 更优的数据响应式&#xff1a;Proxy create-vue 新的脚手架工…

【VIM】VIm-plug插件

如何查找需要的插件 https://github.com/mhinz/vim-startify https://github.com/vim-airline/vim-airline https://github.com/Yggdroot/indentLine github.com/w0ng/vim-hybrid github.com/altercationi/vim-colors-solarized guithub.com/morhetz/gruvbox github.com/sc…

PHP8的静态变量和方法-PHP8知识详解

我们在上一课程讲到了public、private、protected这3个关键字&#xff0c;今天我们来讲解static关键字&#xff0c;明天再讲解final关键字。 如果不想通过创建对象来调用变量或方法&#xff0c;则可以将该变量或方法创建为静态变量或方法&#xff0c;也就是在变量或方法的前面…

什么是博弈论?

什么是博弈&#xff1f;字面描述中&#xff0c;博弈由两个字构成&#xff1a;博 和 弈。博弈是一种双方&#xff08;多方&#xff09;的对抗&#xff08;比赛&#xff09;&#xff0c;对抗总是在一定的规则下进行&#xff0c;参与者必然会考虑应用相应的策略&#xff08;计谋&a…

YOLOv5-PTQ量化部署

目录 前言一、PTQ量化浅析二、YOLOv5模型训练1. 项目的克隆和必要的环境依赖1.1 项目克隆1.2 项目代码结构整体介绍1.3 环境安装 2. 数据集和预训练权重的准备2.1 数据集2.2 预训练权重准备 3. 训练模型3.1 修改数据配置文件3.2 修改模型配置文件3.3 训练模型3.4 mAP测试 三、Y…

ElementUI之增删改及表单验证

⭐⭐本文章收录与ElementUI原创专栏&#xff1a;ElementUI专栏 ⭐⭐ ElementUI的官网&#xff1a;ElementUI官网 目录 一.前言 二.使用ElementUI完成增删改 2.1 后台代码 2.2 前端代码 三.使用ElementUI完成表单验证 一.前言 本章是继上一篇的基础之上在做完善&#xff0…

java Spring Boot按日期 限制大小分文件记录日志

上文 java Spring Boot 将日志写入文件中记录 中 我们实现另一个将控制台日志写入到 项目本地文件的效果 但是 这里有个问题 比如 我项目是个大体量的企业项目 每天会有一百万用户访问 那我每天的日志都记载同一个文件上 那不跟没记没什么区别吗&#xff1f; 东西怎么找&#x…

Windows 安装CMake

CMake 简介 CMake是一个开源的、跨平台的自动化构建系統&#xff0c;用來管理软件构建的过程。 其用途主要包括&#xff1a; 1. 跨平台编译&#xff1a;CMake支援Windows&#xff0c;Mac OS&#xff0c;Linux等多种操作系統&#xff0c;且支援多数主流编译器如GCC&#xff0…

雷达编程实战之功耗优化技术(低功耗)

本篇文章以xWRL6432为例&#xff0c;首先介绍了芯片内部的电源管理框架&#xff0c;在产品业务处理流程的不同阶段&#xff0c;我们可以对不同电源域进行相应的开/关来降低功耗。然后介绍了不同的硬件电源参考设计对芯片功耗的影响&#xff0c;又着重介绍了线性调频脉冲相关参数…

mysql面试题5:索引、主键、唯一索引、联合索引的区别?什么情况下设置了索引但无法使用?并且举例说明

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说索引、主键、唯一索引、联合索引的区别? 索引、主键、唯一索引和联合索引是数据库中常用的索引类型,它们有以下区别: 索引:索引是一种数…

一文带你搞懂Redis持久化

Redis持久化 Redis的数据是存储在内存的&#xff0c;当程序崩溃或者服务器宕机&#xff0c;那么内存里的数据就会丢失。所以避免数据丢失的情况&#xff0c;需要将数据保存到其他的存储设备中。 Redis提供两种方式来持久化&#xff0c;分别是 RDB(Redis Database)&#xff1a…