oss桶权限为私密时,列表查看时桶为私密的文件获取临时url(需添加字典access_policy,先硬编码了,需要可改)

This commit is contained in:
chenchen 2022-10-13 19:24:36 +08:00
parent f7de561ac5
commit a58d058646
8 changed files with 78 additions and 30 deletions

View File

@ -10,6 +10,11 @@ import java.util.List;
*/
public interface OssConstant {
/**
* OSS模块KEY
*/
String SYS_OSS_KEY = "sys_oss:";
/**
* 默认配置KEY
*/

View File

@ -2,6 +2,7 @@ package com.ruoyi.oss.core;
import cn.hutool.core.util.IdUtil;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.HttpMethod;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSCredentialsProvider;
@ -10,7 +11,6 @@ import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
@ -22,6 +22,9 @@ import com.ruoyi.oss.properties.OssProperties;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URL;
import java.time.Instant;
import java.util.Date;
/**
* S3 存储协议 所有兼容S3协议的云厂商均支持
@ -52,16 +55,12 @@ public class OssClient {
} else {
clientConfig.setProtocol(Protocol.HTTP);
}
AmazonS3ClientBuilder build = AmazonS3Client.builder()
this.client = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig)
.withCredentials(credentialsProvider)
.disableChunkedEncoding();
if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)){
// minio 使用https限制使用域名访问 需要此配置 站点填域名
build.enablePathStyleAccess();
}
this.client = build.build();
.disableChunkedEncoding()
.build();
createBucket();
} catch (Exception e) {
@ -96,10 +95,7 @@ public class OssClient {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentType(contentType);
metadata.setContentLength(inputStream.available());
PutObjectRequest putObjectRequest = new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata);
// 设置上传对象的 Acl 为公共读
putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead);
client.putObject(putObjectRequest);
client.putObject(new PutObjectRequest(properties.getBucketName(), path, inputStream, metadata));
} catch (Exception e) {
throw new OssException("上传文件失败,请检查配置信息:[" + e.getMessage() + "]");
}
@ -123,31 +119,18 @@ public class OssClient {
return upload(inputStream, getPath(properties.getPrefix(), suffix), contentType);
}
/**
* 获取文件元数据
*
* @param path 完整文件路径
*/
public ObjectMetadata getObjectMetadata(String path) {
S3Object object = client.getObject(properties.getBucketName(), path);
return object.getObjectMetadata();
}
public String getUrl() {
String domain = properties.getDomain();
if (StringUtils.isNotBlank(domain)) {
return domain;
}
String endpoint = properties.getEndpoint();
String header = OssConstant.IS_HTTPS.equals(properties.getIsHttps()) ? "https://" : "http://";
// 云服务商直接返回
if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)){
if (StringUtils.isNotBlank(domain)) {
return header + domain;
}
if (StringUtils.containsAny(endpoint, OssConstant.CLOUD_SERVICE)) {
return header + properties.getBucketName() + "." + endpoint;
}
// minio 单独处理
if (StringUtils.isNotBlank(domain)) {
return header + domain + "/" + properties.getBucketName();
}
return header + endpoint + "/" + properties.getBucketName();
}
@ -167,6 +150,16 @@ public class OssClient {
return configKey;
}
public String getPrivateUrl(String objectKey, Integer second) {
// objectKey = "file/2022/10/13/81eef51cb0734dedbfa616493a021fe4.jpg";
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(properties.getBucketName(), objectKey)
.withMethod(HttpMethod.GET)
.withExpiration(new Date(Instant.now().toEpochMilli() + 1000 * second));
URL url = client.generatePresignedUrl(generatePresignedUrlRequest);
return url.toString();
}
private static String getPolicy(String bucketName, PolicyType policyType) {
StringBuilder builder = new StringBuilder();
builder.append("{\n\"Statement\": [\n{\n\"Action\": [\n");

View File

@ -50,4 +50,9 @@ public class OssProperties {
*/
private String isHttps;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@ -82,4 +82,8 @@ public class SysOssConfig extends BaseEntity {
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@ -98,4 +98,10 @@ public class SysOssConfigBo extends BaseEntity {
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
@NotBlank(message = "桶权限类型不能为空", groups = {AddGroup.class, EditGroup.class})
private String accessPolicy;
}

View File

@ -82,4 +82,9 @@ public class SysOssConfigVo {
*/
private String remark;
/**
* 桶权限类型(0private 1public 2custom)
*/
private String accessPolicy;
}

View File

@ -8,10 +8,15 @@ import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.oss.constant.OssConstant;
import com.ruoyi.oss.core.OssClient;
import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.exception.OssException;
import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.properties.OssProperties;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo;
@ -27,6 +32,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 文件上传 服务层实现
@ -43,6 +49,20 @@ public class SysOssServiceImpl implements ISysOssService {
public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
List<SysOssVo> filterResult = result.getRecords().stream().map(o -> {
Object json = RedisUtils.getCacheObject(OssConstant.SYS_OSS_KEY + o.getService());
OssProperties properties = JsonUtils.parseObject(json.toString(), OssProperties.class);
if (properties == null) {
throw new OssException("系统异常, '" + o.getService() + "'配置信息不存在!");
}
String privateFlag = "0";
if (properties.getAccessPolicy().equals(privateFlag)) {
OssClient storage = OssFactory.instance(o.getService());
o.setUrl(storage.getPrivateUrl(o.getFileName(), 100));
}
return o;
}).collect(Collectors.toList());
result.setRecords(filterResult);
return TableDataInfo.build(result);
}

View File

@ -151,6 +151,16 @@
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="AccessPolicy">
<el-radio-group v-model="form.accessPolicy">
<el-radio
v-for="dict in dict.type.access_policy"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="域" prop="region">
<el-input v-model="form.region" placeholder="请输入域" />
</el-form-item>
@ -179,7 +189,7 @@ import {
export default {
name: "OssConfig",
dicts: ['sys_yes_no', 'sys_normal_disable'],
dicts: ['sys_yes_no', 'sys_normal_disable','access_policy'],
data() {
return {
// loading