一、前言
上一篇文章介绍了minio之对象存储的访问链路
minio之对象存储常用访问链路介绍_神云瑟瑟的博客-CSDN博客
本篇主要主要介绍标准链路中的临时凭证的生成和使用,以及分享链接的生成
主要的pom文件
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
<version>5.1.7.RELEASE</version>
</dependency>
<!--MINIO-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.3.4</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
<!--fastjson-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
二、临时凭证的生成,并使用
/**
* minio生成临时凭证,上传文件
*/
@Test
public void assumeRoleProviderUpload() {
String policy = "{\n" +
" \"Version\": \"2012-10-17\",\n" +
" \"Statement\": [\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": {\n" +
" \"AWS\": [\n" +
" \"*\"\n" +
" ]\n" +
" },\n" +
" \"Action\": [\n" +
" \"s3:GetBucketLocation\",\n" +
" \"s3:ListBucketMultipartUploads\"\n" +
" ],\n" +
" \"Resource\": [\n" +
" \"arn:aws:s3:::bucket-demo\"\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": {\n" +
" \"AWS\": [\n" +
" \"*\"\n" +
" ]\n" +
" },\n" +
" \"Action\": [\n" +
" \"s3:AbortMultipartUpload\",\n" +
" \"s3:DeleteObject\",\n" +
" \"s3:ListMultipartUploadParts\",\n" +
" \"s3:PutObject\"\n" +
" ],\n" +
" \"Resource\": [\n" +
" \"arn:aws:s3:::bucket-demo/test/**\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}";
try {
//durationSeconds表示多久过期,默认3600秒,如果是小于3600,会被设置成默认值。
AssumeRoleProvider provider = new AssumeRoleProvider(
endpoint, accessKey, secretKey, 3600, policy
, null, null, "roleSessionName", null, null
);
Credentials credentials = provider.fetch();
System.out.println("accessKey:" + credentials.accessKey());
System.out.println("secretKey:" + credentials.secretKey());
System.out.println("sessionToken:" + credentials.sessionToken());
System.out.println(credentials.isExpired());
System.out.println("Credentials ok");
//正常情况下,会将上面临时生成的accessKey,secretKey,sessionToken返给前端,让前端上传。
//使用临时的provider创建minioclient
StaticProvider staticProvider = new StaticProvider(credentials.accessKey(), credentials.secretKey(), credentials.sessionToken());
MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentialsProvider(staticProvider).build();
File file = new File("/Users/shenyunsese/Desktop/pic1.jpg");
//这个objectName的值是经过上面的policy授权的
String objectName = "test/pic1.jpg";
try {
FileInputStream fileInputStream = new FileInputStream(file);
minioClient.putObject(PutObjectArgs.builder().bucket(bucket)
.object(objectName)
.contentType("image/jpg")
.stream(fileInputStream, fileInputStream.available(), -1).build());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("finished");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
使用永久凭证构造AssumeRoleProvider对象,然后得到临时accesskey和secretkey。然后再构造StaticProvider对象最后生成minioclient。
注意点:临时凭证的默认过期时间是1个小时,可以自定义设置,但是如果设置的值小于1小时,会被重置为1小时。
protected static int getValidDurationSeconds(Integer duration) {
return (duration != null && duration > DEFAULT_DURATION_SECONDS)
? duration
: DEFAULT_DURATION_SECONDS;
}
如果在有效期内再使用临时凭证是可以上传的
如果过了有效期,再执行上传就会被拒绝
因为policy权限的resource为"bucket-demo/test/**",是一个范地址,所以在这个地址下还可以上传其他文件
正常情况下为了安全,resource应该根据业务写成具体的地址
三、对私有读的对象生成分享地址
/**
* 生成对象的分享url
*/
@Test
public void share() {
try {
MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
//默认过期时间为7天的秒数,可以自己自定义传入
String sharedUrl = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.bucket(bucket)
.expiry(7 * 24 * 60 * 60)
.object("test/pic1.jpg")
.method(Method.GET)
.build()
);
//生成的分享url
System.out.println(sharedUrl);
//http://192.168.175.117:9000/bucket-demo/test/pic1.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=user_readwrite%2F20220712%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220712T021558Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=2aea03fe33b64796b5ac15883d605874d8bceafd217064b54bfc773f1437cdbb
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
} catch (ServerException e) {
e.printStackTrace();
}
}
生成对象的分享url,默认分享时间为7天,可以自定义传入有效期,时间是以秒为单位。
四、完整的java代码
package test.minio;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.credentials.AssumeRoleProvider;
import io.minio.credentials.Credentials;
import io.minio.credentials.StaticProvider;
import io.minio.errors.*;
import io.minio.http.Method;
import org.junit.Test;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class MinioSafeOpTest {
private String endpoint = "http://192.168.75.117:9000";
private String accessKey = "user_readwrite";
private String secretKey = "user_readwrite_key";
private String bucket = "bucket-demo";
/**
* minio生成临时凭证,上传文件
*/
@Test
public void assumeRoleProviderUpload() {
String policy = "{\n" +
" \"Version\": \"2012-10-17\",\n" +
" \"Statement\": [\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": {\n" +
" \"AWS\": [\n" +
" \"*\"\n" +
" ]\n" +
" },\n" +
" \"Action\": [\n" +
" \"s3:GetBucketLocation\",\n" +
" \"s3:ListBucketMultipartUploads\"\n" +
" ],\n" +
" \"Resource\": [\n" +
" \"arn:aws:s3:::bucket-demo\"\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": {\n" +
" \"AWS\": [\n" +
" \"*\"\n" +
" ]\n" +
" },\n" +
" \"Action\": [\n" +
" \"s3:AbortMultipartUpload\",\n" +
" \"s3:DeleteObject\",\n" +
" \"s3:ListMultipartUploadParts\",\n" +
" \"s3:PutObject\"\n" +
" ],\n" +
" \"Resource\": [\n" +
" \"arn:aws:s3:::bucket-demo/test/**\"\n" +
" ]\n" +
" }\n" +
" ]\n" +
"}";
try {
//durationSeconds表示多久过期,默认3600秒,如果是小于3600,会被设置成默认值。
AssumeRoleProvider provider = new AssumeRoleProvider(
endpoint, accessKey, secretKey, 3600, policy
, null, null, "roleSessionName", null, null
);
Credentials credentials = provider.fetch();
System.out.println("accessKey:" + credentials.accessKey());
System.out.println("secretKey:" + credentials.secretKey());
System.out.println("sessionToken:" + credentials.sessionToken());
System.out.println(credentials.isExpired());
System.out.println("Credentials ok");
//正常情况下,会将上面临时生成的accessKey,secretKey,sessionToken返给前端,让前端上传。
//使用临时的provider创建minioclient
StaticProvider staticProvider = new StaticProvider(credentials.accessKey(), credentials.secretKey(), credentials.sessionToken());
MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentialsProvider(staticProvider).build();
File file = new File("/Users/shenyunsese/Desktop/pic1.jpg");
//这个objectName的值是经过上面的policy授权的
String objectName = "test/pic1.jpg";
try {
FileInputStream fileInputStream = new FileInputStream(file);
minioClient.putObject(PutObjectArgs.builder().bucket(bucket)
.object(objectName)
.contentType("image/jpg")
.stream(fileInputStream, fileInputStream.available(), -1).build());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("finished");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
/**
* 生成对象的分享url
*/
@Test
public void share() {
try {
MinioClient minioClient = MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
//默认过期时间为7天的秒数,可以自己自定义传入
String sharedUrl = minioClient.getPresignedObjectUrl(
GetPresignedObjectUrlArgs.builder()
.bucket(bucket)
.expiry(7 * 24 * 60 * 60)
.object("test/pic1.jpg")
.method(Method.GET)
.build()
);
//生成的分享url
System.out.println(sharedUrl);
//http://192.168.75.117:9000/bucket-demo/test/pic1.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=user_readwrite%2F20220712%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220712T021558Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=2aea03fe33b64796b5ac15883d605874d8bceafd217064b54bfc773f1437cdbb
} catch (ErrorResponseException e) {
e.printStackTrace();
} catch (InsufficientDataException e) {
e.printStackTrace();
} catch (InternalException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidResponseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (XmlParserException e) {
e.printStackTrace();
} catch (ServerException e) {
e.printStackTrace();
}
}
}