mirror of
https://gitee.com/lxp135/minio-plus.git
synced 2025-12-06 08:58:25 +08:00
删除minio自定义实现模块,根据模块规划调整模块名称。
This commit is contained in:
parent
c09c9c3fa8
commit
4de6b0679d
@ -12,6 +12,12 @@
|
|||||||
<artifactId>minio-plus-core</artifactId>
|
<artifactId>minio-plus-core</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
@ -27,7 +33,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-s3-api-definition</artifactId>
|
<artifactId>s3-api-definition</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- google图片压缩 -->
|
<!-- google图片压缩 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@ -13,9 +13,8 @@
|
|||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>minio-s3-api-definition</module>
|
<module>s3-api-definition</module>
|
||||||
<module>minio-s3-api-custom</module>
|
<module>s3-api-minio</module>
|
||||||
<module>minio-s3-api-official</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>minio-s3-api-definition</artifactId>
|
<artifactId>s3-api-definition</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -9,7 +9,7 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<artifactId>minio-s3-api-official</artifactId>
|
<artifactId>s3-api-minio</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-s3-api-definition</artifactId>
|
<artifactId>s3-api-definition</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
@ -12,6 +12,12 @@
|
|||||||
<artifactId>minio-plus-all-spring-boot-starter</artifactId>
|
<artifactId>minio-plus-all-spring-boot-starter</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
@ -19,7 +25,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-s3-api-official</artifactId>
|
<artifactId>s3-api-minio</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,12 @@
|
|||||||
<artifactId>minio-plus-core-spring-boot-starter</artifactId>
|
<artifactId>minio-plus-core-spring-boot-starter</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
@ -19,7 +25,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-s3-api-official</artifactId>
|
<artifactId>s3-api-minio</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>minio-s3-api</artifactId>
|
|
||||||
<groupId>me.liuxp</groupId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
|
|
||||||
<artifactId>minio-s3-api-custom</artifactId>
|
|
||||||
<packaging>jar</packaging>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.hutool</groupId>
|
|
||||||
<artifactId>hutool-all</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>me.liuxp</groupId>
|
|
||||||
<artifactId>minio-s3-api-definition</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>me.liuxp</groupId>
|
|
||||||
<artifactId>minio-plus-common</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
package org.liuxp.minioplus.s3.custom;
|
|
||||||
|
|
||||||
import cn.hutool.http.HttpResponse;
|
|
||||||
import cn.hutool.http.Method;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.liuxp.minioplus.common.config.MinioPlusProperties;
|
|
||||||
import org.liuxp.minioplus.s3.def.ListParts;
|
|
||||||
import org.liuxp.minioplus.s3.def.MinioS3Client;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Repository
|
|
||||||
public class MinioS3ClientImpl implements MinioS3Client {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private MinioPlusProperties properties;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean bucketExists(String bucketName) {
|
|
||||||
|
|
||||||
// 取得当前时间
|
|
||||||
ZonedDateTime date = ZonedDateTime.now();
|
|
||||||
|
|
||||||
// HTTP请求
|
|
||||||
HttpResponse httpResponse = S3Request.request(properties.getKey(),properties.getSecret(),properties.getBackend()
|
|
||||||
,properties.getBackend()+"/"+bucketName,"","/"+bucketName, Method.HEAD.name(),date,0);
|
|
||||||
|
|
||||||
return httpResponse.isOk();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void makeBucket(String bucketName) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String createMultipartUpload(String bucketName, String objectName) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean completeMultipartUpload(String bucketName, String objectName, String uploadId, List<ListParts.Part> parts) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ListParts listParts(String bucketName, String objectName, Integer maxParts, String uploadId) {
|
|
||||||
|
|
||||||
// 获取失败时,拼一个空的返回值
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUploadObjectUrl(String bucketName, String objectName, String uploadId, String partNumber) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getDownloadUrl(String fileName, String contentType, String bucketName, String objectName) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getPreviewUrl(String contentType, String bucketName, String objectName) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean putObject(String bucketName, String objectName, InputStream stream, long size, String contentType) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getObject(String bucketName, String objectName) {
|
|
||||||
return new byte[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeObject(String bucketName, String objectName) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
package org.liuxp.minioplus.s3.custom;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* S3 API 接口定义
|
|
||||||
* @author contact@liuxp.me
|
|
||||||
* @since 2024/06/07
|
|
||||||
*/
|
|
||||||
public enum S3APIEnums {
|
|
||||||
|
|
||||||
BUCKET_EXISTS("检查桶是否存在", "http://localhost:9000/document","/document","HEAD");
|
|
||||||
|
|
||||||
private final String name;
|
|
||||||
private final String url;
|
|
||||||
private final String path;
|
|
||||||
private final String method;
|
|
||||||
|
|
||||||
S3APIEnums(String name,String url,String path,String method) {
|
|
||||||
this.name = name;
|
|
||||||
this.url = url;
|
|
||||||
this.path = path;
|
|
||||||
this.method = method;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getPath() {
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMethod() {
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
package org.liuxp.minioplus.s3.custom;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.http.HttpRequest;
|
|
||||||
import cn.hutool.http.HttpResponse;
|
|
||||||
import cn.hutool.http.HttpUtil;
|
|
||||||
import cn.hutool.http.Method;
|
|
||||||
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class S3Request {
|
|
||||||
|
|
||||||
static String ZERO_MD5_HASH = "1B2M2Y8AsgTpgAmY7PhCfg==";
|
|
||||||
static String ZERO_SHA256_HASH = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
|
|
||||||
|
|
||||||
public static HttpResponse request(String accessKey,String secretKey,String backend,String url, Object body, String path, String method, ZonedDateTime date,int length){
|
|
||||||
|
|
||||||
|
|
||||||
String md5Hash = ZERO_MD5_HASH;
|
|
||||||
if (body instanceof byte[]) {
|
|
||||||
md5Hash = S3Signer.md5Hash((byte[]) body, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 创建除Authorization外所有header
|
|
||||||
Map<String, List<String>> headers = new HashMap<>();
|
|
||||||
headers.put("Host", CollUtil.newArrayList(backend.replace("http://","").replace("https://","")));
|
|
||||||
headers.put("Accept-Encoding", CollUtil.newArrayList("identity"));
|
|
||||||
headers.put("User-Agent", CollUtil.newArrayList("MinIO (Windows 10; amd64) minio-java/8.3.3"));
|
|
||||||
headers.put("Content-MD5", CollUtil.newArrayList(md5Hash));
|
|
||||||
headers.put("x-amz-content-sha256", CollUtil.newArrayList(ZERO_SHA256_HASH));
|
|
||||||
headers.put("x-amz-date", CollUtil.newArrayList(date.format(Time.AMZ_DATE_FORMAT)));
|
|
||||||
|
|
||||||
// 计算authorization
|
|
||||||
String authorization = S3Signer.build(accessKey,secretKey,date,headers,"",method,path,ZERO_SHA256_HASH);
|
|
||||||
|
|
||||||
HttpRequest httpRequest = HttpUtil.createRequest(Method.HEAD, url);
|
|
||||||
httpRequest.header(headers,true);
|
|
||||||
httpRequest.header("Authorization", authorization);
|
|
||||||
|
|
||||||
return httpRequest.execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,228 +0,0 @@
|
|||||||
package org.liuxp.minioplus.s3.custom;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.text.CharSequenceUtil;
|
|
||||||
import cn.hutool.core.util.HexUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.MessageDigest;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class S3Signer {
|
|
||||||
|
|
||||||
private static final String serviceName = "s3";
|
|
||||||
private static final String US_EAST_1 = "us-east-1";
|
|
||||||
private static final Set<String> IGNORED_HEADERS = CollUtil.set(true,"accept-encoding", "authorization", "content-type", "content-length", "user-agent");
|
|
||||||
|
|
||||||
public static String build(String accessKey,String secretKey,ZonedDateTime date,Map<String, List<String>> headers,String params,String method,String path,String zeroSha256Hash){
|
|
||||||
|
|
||||||
try {
|
|
||||||
// 计算scope
|
|
||||||
String scope = buildScope(date);
|
|
||||||
|
|
||||||
// 计算signedHeaders
|
|
||||||
Map<String, String> canonicalHeaders = buildCanonicalHeaders(headers);
|
|
||||||
|
|
||||||
// 计算signedHeaders
|
|
||||||
String signedHeaders = buildSignedHeaders(canonicalHeaders);
|
|
||||||
|
|
||||||
// 计算canonicalQueryString
|
|
||||||
String canonicalQueryString = buildCanonicalQueryString(params);
|
|
||||||
|
|
||||||
// 计算buildCanonicalRequest
|
|
||||||
String canonicalRequestHash = buildCanonicalRequest(canonicalHeaders,signedHeaders,canonicalQueryString,method,path,zeroSha256Hash);
|
|
||||||
|
|
||||||
// 计算stringToSign
|
|
||||||
String stringToSign = buildStringToSign(date,scope,canonicalRequestHash);
|
|
||||||
|
|
||||||
// 计算signingKey
|
|
||||||
byte[] signingKey = buildSigningKey(date,secretKey);
|
|
||||||
|
|
||||||
// 计算signature
|
|
||||||
String signature = buildSignature(signingKey,stringToSign);
|
|
||||||
|
|
||||||
// 计算authorization
|
|
||||||
String authorization = buildAuthorization(accessKey,scope,signedHeaders,signature);
|
|
||||||
|
|
||||||
log.debug("httpRequest.headers()="+headers);
|
|
||||||
log.debug("scope="+scope);
|
|
||||||
log.debug("canonicalHeaders="+canonicalHeaders);
|
|
||||||
log.debug("signedHeaders="+signedHeaders);
|
|
||||||
log.debug("canonicalQueryString="+canonicalQueryString);
|
|
||||||
log.debug("canonicalRequestHash="+canonicalRequestHash);
|
|
||||||
log.debug("stringToSign="+stringToSign);
|
|
||||||
log.debug("signature="+signature);
|
|
||||||
log.debug("authorization="+authorization);
|
|
||||||
|
|
||||||
return authorization;
|
|
||||||
}catch (Exception e){
|
|
||||||
throw new RuntimeException("S3签名失败", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 计算scope
|
|
||||||
private static String buildScope(ZonedDateTime date){
|
|
||||||
return date.format(Time.SIGNER_DATE_FORMAT) + "/" + US_EAST_1 + "/" + serviceName + "/aws4_request";
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Map<String, String> buildCanonicalHeaders(Map<String, List<String>> headers){
|
|
||||||
Map<String, String> canonicalHeaders = new TreeMap<>();
|
|
||||||
|
|
||||||
for (String name : headers.keySet()) {
|
|
||||||
String signedHeader = name.toLowerCase(Locale.US);
|
|
||||||
if (!IGNORED_HEADERS.contains(signedHeader)) {
|
|
||||||
// Convert and add header values as per
|
|
||||||
// https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html
|
|
||||||
// * Header having multiple values should be converted to comma separated values.
|
|
||||||
// * Multi-spaced value of header should be trimmed to single spaced value.
|
|
||||||
canonicalHeaders.put(
|
|
||||||
signedHeader,
|
|
||||||
headers.get(name).stream()
|
|
||||||
.map(
|
|
||||||
value -> {
|
|
||||||
return value.replaceAll("( +)", " ");
|
|
||||||
})
|
|
||||||
.collect(Collectors.joining(",")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return canonicalHeaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算signedHeaders
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String buildSignedHeaders(Map<String, String> canonicalHeaders) {
|
|
||||||
return CharSequenceUtil.join(";", canonicalHeaders.keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildCanonicalQueryString(String params){
|
|
||||||
|
|
||||||
if(CharSequenceUtil.isBlank(params)){
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
return params;
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
|
|
||||||
// MapUtil
|
|
||||||
|
|
||||||
// Building a multimap which only order keys, ordering values is not performed
|
|
||||||
// until MinIO server supports it.
|
|
||||||
// Multimap<String, String> signedQueryParams =
|
|
||||||
// MultimapBuilder.treeKeys().arrayListValues().build();
|
|
||||||
//
|
|
||||||
// for (String queryParam : params.split("&")) {
|
|
||||||
// String[] tokens = queryParam.split("=");
|
|
||||||
// if (tokens.length > 1) {
|
|
||||||
// signedQueryParams.put(tokens[0], tokens[1]);
|
|
||||||
// } else {
|
|
||||||
// signedQueryParams.put(tokens[0], "");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return Joiner.on("&").withKeyValueSeparator("=").join(signedQueryParams.entries());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String buildCanonicalRequest(Map<String, String> canonicalHeaders,String signedHeaders
|
|
||||||
,String canonicalQueryString,String method,String path,String zeroSha256Hash) throws NoSuchAlgorithmException {
|
|
||||||
|
|
||||||
StringBuilder headers = new StringBuilder();
|
|
||||||
for (String key : canonicalHeaders.keySet()) {
|
|
||||||
|
|
||||||
headers.append(key);
|
|
||||||
headers.append(":");
|
|
||||||
headers.append(canonicalHeaders.get(key));
|
|
||||||
headers.append("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
String canonicalRequest = method + "\n" + path + "\n" + canonicalQueryString + "\n"
|
|
||||||
+ headers + "\n" + signedHeaders + "\n" + zeroSha256Hash;
|
|
||||||
log.debug("canonicalRequest="+canonicalRequest);
|
|
||||||
|
|
||||||
byte[] data = canonicalRequest.getBytes(StandardCharsets.UTF_8);
|
|
||||||
MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256");
|
|
||||||
sha256Digest.update(data, 0, data.length);
|
|
||||||
|
|
||||||
return HexUtil.encodeHexStr(sha256Digest.digest());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算stringToSign
|
|
||||||
* @param date
|
|
||||||
* @param scope
|
|
||||||
* @param canonicalRequestHash
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String buildStringToSign(ZonedDateTime date,String scope,String canonicalRequestHash){
|
|
||||||
return "AWS4-HMAC-SHA256" + "\n" + date.format(Time.AMZ_DATE_FORMAT) + "\n" + scope + "\n" + canonicalRequestHash;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算signingKey
|
|
||||||
* @param date
|
|
||||||
* @return
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
* @throws InvalidKeyException
|
|
||||||
*/
|
|
||||||
private static byte[] buildSigningKey(ZonedDateTime date,String secretKey) throws NoSuchAlgorithmException, InvalidKeyException {
|
|
||||||
String aws4SecretKey = "AWS4" + secretKey;
|
|
||||||
byte[] dateKey = sumHmac(aws4SecretKey.getBytes(StandardCharsets.UTF_8), date.format(Time.SIGNER_DATE_FORMAT).getBytes(StandardCharsets.UTF_8));
|
|
||||||
byte[] dateRegionKey = sumHmac(dateKey, US_EAST_1.getBytes(StandardCharsets.UTF_8));
|
|
||||||
byte[] dateRegionServiceKey = sumHmac(dateRegionKey, serviceName.getBytes(StandardCharsets.UTF_8));
|
|
||||||
return sumHmac(dateRegionServiceKey, "aws4_request".getBytes(StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算signature
|
|
||||||
* @param signingKey
|
|
||||||
* @param stringToSign
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String buildSignature(byte[] signingKey,String stringToSign) throws NoSuchAlgorithmException, InvalidKeyException {
|
|
||||||
byte[] digest = sumHmac(signingKey, stringToSign.getBytes(StandardCharsets.UTF_8));
|
|
||||||
return HexUtil.encodeHexStr(digest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算authorization
|
|
||||||
* @param accessKey
|
|
||||||
* @param scope
|
|
||||||
* @param signedHeaders
|
|
||||||
* @param signature
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
private static String buildAuthorization(String accessKey,String scope,String signedHeaders,String signature){
|
|
||||||
return "AWS4-HMAC-SHA256 Credential=" + accessKey + "/" + scope + ", SignedHeaders=" + signedHeaders + ", Signature=" + signature;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] sumHmac(byte[] key, byte[] data) throws NoSuchAlgorithmException, InvalidKeyException {
|
|
||||||
Mac mac = Mac.getInstance("HmacSHA256");
|
|
||||||
|
|
||||||
mac.init(new SecretKeySpec(key, "HmacSHA256"));
|
|
||||||
mac.update(data);
|
|
||||||
|
|
||||||
return mac.doFinal();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String md5Hash(byte[] data, int length) {
|
|
||||||
try {
|
|
||||||
MessageDigest md5Digest = MessageDigest.getInstance("MD5");
|
|
||||||
md5Digest.update(data, 0, length);
|
|
||||||
return Base64.getEncoder().encodeToString(md5Digest.digest());
|
|
||||||
}catch (Exception e){
|
|
||||||
throw new RuntimeException("md5Hash失败", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package org.liuxp.minioplus.s3.custom;/*
|
|
||||||
* MinIO Java SDK for Amazon S3 Compatible Cloud Storage,
|
|
||||||
* (C) 2020 MinIO, Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.time.format.DateTimeFormatter;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
/** Time formatters for S3 APIs. */
|
|
||||||
public class Time {
|
|
||||||
public static final ZoneId UTC = ZoneId.of("Z");
|
|
||||||
|
|
||||||
public static final DateTimeFormatter AMZ_DATE_FORMAT =
|
|
||||||
DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'", Locale.US).withZone(UTC);
|
|
||||||
|
|
||||||
public static final DateTimeFormatter RESPONSE_DATE_FORMAT =
|
|
||||||
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH':'mm':'ss'.'SSS'Z'", Locale.US).withZone(UTC);
|
|
||||||
|
|
||||||
// Formatted string is convertible to LocalDate only, not to LocalDateTime or ZonedDateTime.
|
|
||||||
// Below example shows how to use this to get ZonedDateTime.
|
|
||||||
// LocalDate.parse("20200225", SIGNER_DATE_FORMAT).atStartOfDay(UTC);
|
|
||||||
public static final DateTimeFormatter SIGNER_DATE_FORMAT =
|
|
||||||
DateTimeFormatter.ofPattern("yyyyMMdd", Locale.US).withZone(UTC);
|
|
||||||
|
|
||||||
public static final DateTimeFormatter HTTP_HEADER_DATE_FORMAT =
|
|
||||||
DateTimeFormatter.ofPattern("EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'", Locale.US).withZone(UTC);
|
|
||||||
|
|
||||||
public static final DateTimeFormatter EXPIRATION_DATE_FORMAT = RESPONSE_DATE_FORMAT;
|
|
||||||
|
|
||||||
private Time() {}
|
|
||||||
}
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
|
||||||
org.liuxp.minioplus.s3.custom.MinioS3ClientImpl
|
|
||||||
@ -1,54 +0,0 @@
|
|||||||
import cn.hutool.http.HttpResponse;
|
|
||||||
import org.liuxp.minioplus.s3.custom.S3Request;
|
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
|
||||||
|
|
||||||
public class S3RequestTest {
|
|
||||||
|
|
||||||
|
|
||||||
// public static void main(String[] args){
|
|
||||||
//
|
|
||||||
// String accessKey = "minioadmin";
|
|
||||||
// String secretKey = "minioadmin";
|
|
||||||
// String backend = "http://localhost:9000";
|
|
||||||
// String bucket = "document";
|
|
||||||
//// String url = "http://localhost:9000/document1";
|
|
||||||
//
|
|
||||||
//// ZonedDateTime date = ZonedDateTime.parse("2024-05-31T16:31:54Z");
|
|
||||||
// // 取得当前时间
|
|
||||||
// ZonedDateTime date = ZonedDateTime.now();
|
|
||||||
//
|
|
||||||
// HttpResponse httpResponse = S3Request.request(accessKey,secretKey,backend,backend+"/"+bucket,"","/"+bucket,"HEAD",date);
|
|
||||||
//
|
|
||||||
// System.out.println("httpResponse.isOk()="+httpResponse.isOk());
|
|
||||||
// System.out.println("httpResponse.getStatus()="+httpResponse.getStatus());
|
|
||||||
// System.out.println("httpResponse.headers()="+httpResponse.headers());
|
|
||||||
// System.out.println("httpResponse.body()="+httpResponse.body());
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static void main(String[] args){
|
|
||||||
|
|
||||||
String accessKey = "minioadmin";
|
|
||||||
String secretKey = "minioadmin";
|
|
||||||
String backend = "http://localhost:9000";
|
|
||||||
String bucket = "document223";
|
|
||||||
// String url = "http://localhost:9000/document1";
|
|
||||||
|
|
||||||
// ZonedDateTime date = ZonedDateTime.parse("2024-05-31T16:31:54Z");
|
|
||||||
// 取得当前时间
|
|
||||||
ZonedDateTime date = ZonedDateTime.now();
|
|
||||||
|
|
||||||
byte[] EMPTY_BODY = new byte[] {};
|
|
||||||
|
|
||||||
HttpResponse httpResponse = S3Request.request(accessKey,secretKey,backend,backend+"/"+bucket,EMPTY_BODY,"/"+bucket,"PUT",date,0);
|
|
||||||
|
|
||||||
System.out.println("httpResponse.isOk()="+httpResponse.isOk());
|
|
||||||
System.out.println("httpResponse.getStatus()="+httpResponse.getStatus());
|
|
||||||
System.out.println("httpResponse.headers()="+httpResponse.headers());
|
|
||||||
System.out.println("httpResponse.body()="+httpResponse.body());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
13
pom.xml
13
pom.xml
@ -40,8 +40,8 @@
|
|||||||
<module>minio-plus-common</module>
|
<module>minio-plus-common</module>
|
||||||
<module>minio-plus-core</module>
|
<module>minio-plus-core</module>
|
||||||
<module>minio-plus-extension</module>
|
<module>minio-plus-extension</module>
|
||||||
|
<module>minio-plus-s3-api</module>
|
||||||
<module>minio-plus-spring-boot-starter</module>
|
<module>minio-plus-spring-boot-starter</module>
|
||||||
<module>minio-s3-api</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
@ -49,7 +49,7 @@
|
|||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
||||||
<revision>0.1.4</revision>
|
<revision>0.1.5</revision>
|
||||||
<spring-boot.version>2.7.18</spring-boot.version>
|
<spring-boot.version>2.7.18</spring-boot.version>
|
||||||
<mybatisplus.version>3.5.7</mybatisplus.version>
|
<mybatisplus.version>3.5.7</mybatisplus.version>
|
||||||
<lombok.version>1.18.32</lombok.version>
|
<lombok.version>1.18.32</lombok.version>
|
||||||
@ -154,7 +154,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-s3-api-definition</artifactId>
|
<artifactId>s3-api-definition</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -164,7 +164,7 @@
|
|||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>me.liuxp</groupId>
|
<groupId>me.liuxp</groupId>
|
||||||
<artifactId>minio-s3-api-official</artifactId>
|
<artifactId>s3-api-minio</artifactId>
|
||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
@ -305,10 +305,7 @@
|
|||||||
<artifactId>dependency-check-maven</artifactId>
|
<artifactId>dependency-check-maven</artifactId>
|
||||||
<version>10.0.3</version>
|
<version>10.0.3</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<skipRuntimeScope>true</skipRuntimeScope>
|
<skip>true</skip>
|
||||||
<skipProvidedScope>true</skipProvidedScope>
|
|
||||||
<skipSystemScope>true</skipSystemScope>
|
|
||||||
<skipTestScope>true</skipTestScope>
|
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
<execution>
|
<execution>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user