minio是一个文件存储服务器,他实现了亚马逊s3协议,所以在文件管理管理上有着更加细粒的权限划分,同时它有着部署简便,支持大数据存储,上传下载速度快。分布式部署可以实现纠删码防止文件丢失特性。今天这篇文章主要讲minio桶的策略实现方式
minio8.0版本和之前版本就设置策略这个方法就着非常明显的差异
public class SetBucketPolicy {
public static void main(String[] args)
throws IOException, NoSuchAlgorithmException, InvalidKeyException, XmlPullParserException {
try {
// 新建客户端
MinioClient minioClient = new MinioClient("地址", "用户名",
"密码");
// 如果对整个桶设置,路径直接设置 *
// 如果对指定前缀设置 前缀/路径
minioClient.setBucketPolicy("桶名", "前缀/路径", PolicyType.READ_ONLY);
} catch (MinioException e) {
System.out.println("Error occurred: " + e);
}
}
}
PolicyType提供多种常量包括只读,只读,读写等。并且第二个参数前缀设置更好的设置桶下的文件夹策略。
**but-----------------------**到了8.0后官方给出的方法非常扯淡,需要传s3指定json格式的字符串。本人实在没有相通这个操作的意义。(可能为了和其他大厂的服务器协议相同)
public class SetBucketPolicy {
public static void main(String[] args)
throws IOException, NoSuchAlgorithmException, InvalidKeyException, XmlPullParserException {
try {
// 新建客户端
MinioClient minioClient = new MinioClient("地址", "用户名",
"密码");
try {
// 如何获取对应json字符串
String config = " [\n" +
" {\n" +
" \"Action\": [\n" +
" \"s3:GetBucketLocation\",\n" +
" \"s3:ListBucket\"\n" +
" ],\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": \"*\",\n" +
" \"Resource\": \"arn:aws:s3:::my-bucketname\"\n" +
" },\n" +
" {\n" +
" \"Action\": \"s3:GetObject\",\n" +
" \"Effect\": \"Allow\",\n" +
" \"Principal\": \"*\",\n" +
" \"Resource\": \"arn:aws:s3:::my-bucketname/myobject*\"\n" +
" }\n" +
" ],\n" +
" \"Version\": \"2012-10-17\"\n" +
" }"
this.minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(config).build());
} catch (ErrorResponseException | InsufficientDataException
| InternalException | InvalidKeyException
| InvalidResponseException | IOException
| NoSuchAlgorithmException | ServerException
| XmlParserException e) {
log.error("[seed] [minio] 设置桶:{}策略失败", bucketName, e);
}
}
}
首先我们来看看minio提供的管理平台页面
我们可与看到在IAM Policies栏目中存在几种桶策略,这种策略更像是给minio平台的其他用户赋予的策略。也就是说你使用mc或者其他方法在minio上创建了其他的管理员账号,这个账号的权限就是你通过给他赋值这些策略完成的,当然你可以生成其他你想生成的这种策略赋值给用户。而Principal这个字段为用户范围。或者将用户划分为组,给组添加策略。就能实现某些用户(组)登录后台时只能看到策略内他能看到的桶,以及对桶的操作。
**BUT------------**在通过java对桶进行操作时,我们只需要如下创建一个minioclient进行文件操作,也就不需要其他用户,只需要超管的账号密码就能完成基本的操作,那么如何java对桶实现读写权限管理呢?
// 新建客户端
MinioClient minioClient = new MinioClient("地址", "用户名",
"密码");
通过代码调用新建桶发现新建桶策略json格式的字符串为空字符串,管理平台策略默认为private,不能通过浏览器直接访问
上面我们已经说了,要么你是管理员,然后创建用户client,调用接口。如果你带有想要访问桶的策略,那么你就能拿到你想要的文件。如果你不是,就只能默认使用超管账号生成minioclient对象调用。那么有没有一种可能就是我既不是超管,又不是管理员,或者管理员没权限。我也想拿到这个桶里的文件或者操作他。**是可以的!**通过设置桶的访问规则。
1)将summary中的access policy桶策略修改为public,那么就可以通过ip:port/bucketname来对文件进行访问
2)访问规则就是只读,只写,读写。可以匹配前缀,也就是匹配桶下的文件夹,指定文件夹访问规则。
只需要将所有的权限或者目标设置为*,我们遵循一下官方的写法,我将新建桶手动设置为public,通过代码获取json字符串
String s = "{\"Version\":\"2012-10-17\"," +
"\"Statement\":[{\"Effect\":\"Allow\"," +
"\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:ListBucketMultipartUploads\",\"s3:GetBucketLocation\",\"s3:ListBucket\"]," +
"\"Resource\":[\"arn:aws:s3:::new\"]}," +
"{\"Effect\":\"Allow\"," +
"\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\"]," +
"\"Resource\":[\"arn:aws:s3:::new/*\"]}]}";
解释:
Statement中的第一个对象更像是管理员的权限,如ListBucketMultipartUploads为分片上传,GetBucketLocation获取桶的地址,ListBucket获取桶内文件,而Resource为作用于那个桶
而-------------------------第二个对象像是对桶的规则描述
Principal为表示所有人,Action中的权限是可以对new桶下所有的地方进行增删改查操作
在实际的业务中,往往会使用实际业务中的用户id作为该用户在文件服务器中的桶,该用户所有的文件就存在这个桶下,那么这个用户如果要公开一些文件,而让一些文件保持私密呢。
手动在新桶下创建多个文件夹,手动修改文件夹权限,来获取json字符串进行分析
分别创建四个次级文件夹manchao,2,3,tokyo-hot,设置规则如图
获取桶策略文件
String h = "{\"Version\":\"2012-10-17\"," +
"\"Statement\":" +
"[{\"Effect\":\"Allow\"," +
"\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"]," +
"\"Resource\":[\"arn:aws:s3:::pic\"]}," +
//条件查询语句
"{\"Effect\":\"Allow\"," +
"\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:ListBucket\"]," +
"\"Resource\":[\"arn:aws:s3:::pic\"]," +
"\"Condition\":{\"StringEquals\":{\"s3:prefix\":[\"3/manchao\",\"manchao\",\"2\"]}}}," +
"" +
"{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:ListMultipartUploadParts\"," +
"\"s3:PutObject\",\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:GetObject\"]," +
"\"Resource\":[\"arn:aws:s3:::pic/manchao*\"]}," +
"" +
"{\"Effect\":\"Allow\"," +
"\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:GetObject\"]," +
"\"Resource\":[\"arn:aws:s3:::pic/2*\",\"arn:aws:s3:::pic/3/manchao*\"]}," +
"" +
"{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]}," +
"\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"]," +
"\"Resource\":[\"arn:aws:s3:::pic/tokyo-hot*\"]}]}";
可以看到有一个条件查询的语句,并且在前缀匹配只匹配到pic桶下可读和可读写的文件夹
读,写,读写分别为三个Statement集合下的对象,对应三个规则,三个规则action和resource分别为不同的值,并且多个路径和权限用,隔开
如上,我创建manchao和3文件夹,3文件夹下我创建manchao文件夹,设置prefix为manchao规则为可读,3/manchao下的文件会被访问到吗?答案是不能
prefix实际为文件(夹)名,会严格按照文件夹路径匹配
在方法中传入json字符串就完成了。为了方便,你可以将可读,可写,读写的action提取出来进行字符串替换,在resource中的路径进行替换。
没有,我都还没搞明白