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 { public interface OssConstant {
/**
* OSS模块KEY
*/
String SYS_OSS_KEY = "sys_oss:";
/** /**
* 默认配置KEY * 默认配置KEY
*/ */

View File

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

View File

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

View File

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

View File

@ -98,4 +98,10 @@ public class SysOssConfigBo extends BaseEntity {
*/ */
private String remark; 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; 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.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.JsonUtils;
import com.ruoyi.common.utils.StringUtils; 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.core.OssClient;
import com.ruoyi.oss.entity.UploadResult; import com.ruoyi.oss.entity.UploadResult;
import com.ruoyi.oss.exception.OssException;
import com.ruoyi.oss.factory.OssFactory; import com.ruoyi.oss.factory.OssFactory;
import com.ruoyi.oss.properties.OssProperties;
import com.ruoyi.system.domain.SysOss; import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.domain.bo.SysOssBo; import com.ruoyi.system.domain.bo.SysOssBo;
import com.ruoyi.system.domain.vo.SysOssVo; import com.ruoyi.system.domain.vo.SysOssVo;
@ -27,6 +32,7 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Map; 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) { public TableDataInfo<SysOssVo> queryPageList(SysOssBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo); LambdaQueryWrapper<SysOss> lqw = buildQueryWrapper(bo);
Page<SysOssVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); 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); return TableDataInfo.build(result);
} }

View File

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