美文网首页
在Minio以STS方式获得临时凭据上传文件

在Minio以STS方式获得临时凭据上传文件

作者: 张云飞Vir | 来源:发表于2023-04-11 16:52 被阅读0次

    一、写在前面

    一个常见的场景是:需要让客户端来上传图片,面临的安全性问题。给与客户端永久凭据无疑是很大风险的,我们还可以选择“给予一个临时凭据,这个凭据关联到一个 授权的用户,我们可以随时停用和修改这个用户具有的权限”

    Minio提供了STS 的方式来实现这个方法。

    MinIO安全令牌服务(STS)API允许应用程序生成用于访问MinIO部署的临时凭据。参考https://min.io/docs/minio/linux/developers/security-token-service.html

    整体方案是:

    1. Minio服务器的web页面创建一个 用户和策略
    2. Java应用服务通过 使用上面的用户信息 使用 API 可取得临时的 凭据 token
    3. 将 临时凭据 给到前端 Web,或者App
    4. 前端使用 临时凭据 和 js API 等,进行对象的上传,获得等。

    二、部署和启动 Minio

    2.1、安装

    wget https://dl.min.io/server/minio/release/linux-amd64//minio
    chmod +x minio
    

    这时可使用 ./minio 了

    2.2 启动

    ./minio server /mnt/data

    注意:/mnt/data 是图片存放位置

    为了使用方便,自己写个启动脚本

    export MINIO_ROOT_USER=admin
    export MINIO_ROOT_PASSWORD=password
    export MINIO_REGION=cn-beijing-2
    nohup ./minio server /mnt/data &
    

    *注意:

    • MINIO_ROOT_USER 你的管理员账号
    • MINIO_ROOT_PASSWORD 你的管理员密码
    • MINIO_REGION 是你指定的区域名

    2.3 访问控制台

    打开网页: http://你的机器:9000

    三、配置临时凭据相关的设置项

    我采用 web控制台页面来设置,比较方便。
    打开 http://你的机器:9000 , 登录进去

    3.1、登录控制面板,创建策略

    image.png image.png

    图片中编号3: 填写个策略名
    图片中编号4: 填写 json 格式描述的具体策略

    可以按我的填,下面的json描述了一个可读,写,删,获得桶位置的策略。

    
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "s3:GetObject",
                    "s3:PutObject",
                    "s3:DeleteObject",
                    "s3:GetBucketLocation"
                ],
                "Resource": [
                    "arn:aws:s3:::*"
                ]
            }
        ]
    }
    

    3.2、创建用户,绑定策略

    image.png image.png

    图片中编号4:填写一个 用户名(随便填,记下来要用)
    图片中编号5:填写一个 密码(随便填,记下来要用)
    图片中编号6:打钩选一个策略,就是我们上面 创建的策略 勾选上。

    四、通过Java 获得凭据并上传和获得上传后的URL

    1、创一个Maven项目
    2、 加入依赖

    <dependency>
                <groupId>io.minio</groupId>
                <artifactId>minio</artifactId>
                <version>8.3.3</version>
     </dependency>
    

    3、取得临时凭据
    一些静态变量定义

     //服务所在ip地址和端口
        public static final String ENDPOINT = "http://10.0.0.102:9000/";
    
        //mc的用户名
        public static final String ACCESS_KEY_COMPANY = "sts-user";
        //mc的密码
        public static final String SECRET_KEY_COMPANY = "sts-password";
        //aws服务端点
        public static final String REGION = "cn-beijing-2";
        //上传的bucket名
        public static final String BUCKET = "test";
        //授权策略,允许访问名为bucket的桶的目录
        public static final String ROLE_ARN = "arn:aws:s3:::test/*";
        public static final String ROLE_SESSION_NAME = "anysession";
        //定义策略,可进行二次限定
        public static final String POLICY_GET_AND_PUT = "{\n" +
                " \"Version\": \"2012-10-17\",\n" +
                " \"Statement\": [\n" +
                "  {\n" +
                "   \"Effect\": \"Allow\",\n" +
                "   \"Action\": [\n" +
                "    \"s3:GetObject\",\n" +
                "    \"s3:GetBucketLocation\",\n" +
                "    \"s3:PutObject\"\n" +
                "   ],\n" +
                "   \"Resource\": [\n" +
                "    \"arn:aws:s3:::test/*\"\n" +
                "   ]\n" +
                "  }\n" +
                " ]\n" +
                "}";
    
    

    得到 临时凭据

     /**
         * 得到 临时凭据
         */
        private static Credentials getCredentials() throws NoSuchAlgorithmException {
            int durationSeconds = 360000;//秒
            //创建签名对象
            AssumeRoleProvider provider = new AssumeRoleProvider(
                    ENDPOINT,
                    ACCESS_KEY_COMPANY,
                    SECRET_KEY_COMPANY,
                    durationSeconds,//默认3600秒失效,设置小于这个就是3600,大于3600就实际值
                    POLICY_GET_AND_PUT,
                    REGION,
                    ROLE_ARN,
                    ROLE_SESSION_NAME,
                    null,
                    null);
            Date expirationDate = DateUtil.getDateByAddMinute(new Date(), durationSeconds / 60);
            /**
             * 打印provider签名属性
             */
            System.out.println("sessionToken=" + provider.fetch().sessionToken());
            System.out.println("accessKey=" + provider.fetch().accessKey());
            System.out.println("secretKey=" + provider.fetch().secretKey());
            System.out.println("isExpired=" + provider.fetch().isExpired());
            System.out.println("expirationDate=" + DateUtil.getDateTimeFormat(expirationDate));
    
            Credentials credentials = provider.fetch();
            String sessionToken = provider.fetch().sessionToken();
            String accessKey = provider.fetch().accessKey();
            String secretKey = provider.fetch().secretKey();
            return credentials;
        }
    
        // 上传
        private static void putObject(File file, String objectName, Credentials credentials) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
            StaticProvider staticProvider = new StaticProvider(credentials.accessKey(), credentials.secretKey(), credentials.sessionToken());
            MinioClient minioClient = MinioClient.builder().endpoint(ENDPOINT).credentialsProvider(staticProvider).build();
            //这个objectName的值是经过上面的policy授权的
            FileInputStream fileInputStream = new FileInputStream(file);
            minioClient.putObject(PutObjectArgs.builder().bucket(BUCKET)
                    .object(objectName)
                    .contentType("image/jpg")
                    .stream(fileInputStream, fileInputStream.available(), -1).build());
        }
    
        // 获得一个 可过期的 URL
        private static String getObjectUrl(String objectName2,Credentials credentials) throws ErrorResponseException, InsufficientDataException, InternalException, InvalidKeyException, InvalidResponseException, IOException, NoSuchAlgorithmException, XmlParserException, ServerException {
            StaticProvider staticProvider = new StaticProvider(credentials.accessKey(), credentials.secretKey(), credentials.sessionToken());
            MinioClient minioClient = MinioClient.builder().endpoint(ENDPOINT).credentialsProvider(staticProvider).build();
            String url =
                    minioClient.getPresignedObjectUrl(
                            GetPresignedObjectUrlArgs.builder()
                                    .method(Method.GET)
                                    .bucket(BUCKET)
                                    .object(objectName2)
                                    .expiry(2, TimeUnit.HOURS) //过期时间
                                    //.extraQueryParams(reqParams)
                                    .build());
            System.out.println(url);
            return url;
        }
    

    五、参考:

    https://blog.csdn.net/yilvqingtai/article/details/126059858
    https://min.io/docs/minio/linux/developers/java/API.html

    相关文章

      网友评论

          本文标题:在Minio以STS方式获得临时凭据上传文件

          本文链接:https://www.haomeiwen.com/subject/cuigddtx.html