zhaowenyu
2026-04-01 0a0174e3b784f7f9f7c3abfb419c23ee26709d0f
ard-sample/src/main/java/com/ard/sample/storage/service/impl/StorageServiceImpl.java
@@ -1,22 +1,34 @@
package com.ard.sample.storage.service.impl;
import com.ard.common.config.OssConfiguration;
import com.ard.oss.model.CredentialsDTO;
import com.ard.sample.component.mqtt.model.*;
import com.ard.sample.component.mqtt.service.IMessageSenderService;
import com.ard.oss.model.StsCredentialsDTO;
import com.ard.sample.config.DockConfiguration;
import com.ard.sample.storage.service.IStorageService;
import com.ard.oss.service.impl.OssServiceContext;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.credentials.StaticProvider;
import io.minio.errors.MinioException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.mqtt.support.MqttHeaders;
import org.springframework.messaging.MessageHeaders;
import org.springframework.stereotype.Service;
import java.io.ByteArrayInputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
/**
 * @author sean
 * @version 0.3
 * @date 2022/3/9
 */
@Slf4j
@Service
public class StorageServiceImpl implements IStorageService {
@@ -28,19 +40,43 @@
    @Override
    public StsCredentialsDTO getSTSCredentials() {
        CredentialsDTO credentials = ossService.getCredentials();
        log.info("验证https临时凭证是否有效:{}", credentials);
        execMinio(OssConfiguration.endpoint,
                credentials.getAccessKeyId(),
                credentials.getAccessKeySecret(),
                credentials.getSecurityToken(),
                OssConfiguration.region,
                DockConfiguration.bucket,
                "test_object_https");
        return StsCredentialsDTO.builder()
                .endpoint(OssConfiguration.endpoint)
                .bucket(OssConfiguration.bucket)
                .credentials(ossService.getCredentials())
                //机场媒体库minio配置信息用代理地址,桶用机场的桶。
                .endpoint(DockConfiguration.endpoint)
                .bucket(DockConfiguration.bucket)
                .credentials(credentials)
                .provider(OssConfiguration.provider)
                .objectKeyPrefix(OssConfiguration.objectDirPrefix)
                .region(OssConfiguration.region)
                .build();
//        return StsCredentialsDTO.builder()
//                //机场媒体库minio配置信息用代理地址,桶用机场的桶。
//                .endpoint(OssConfiguration.endpoint)
//                .bucket(OssConfiguration.bucket)
////                .credentials(ossService.getCredentials())
//                .credentials(credentials)
//                .provider(OssConfiguration.provider)
//                .objectKeyPrefix(OssConfiguration.objectDirPrefix)
//                .region(OssConfiguration.region)
//                .build();
    }
    @Override
    @ServiceActivator(inputChannel = ChannelName.INBOUND_REQUESTS_STORAGE_CONFIG_GET, outputChannel = ChannelName.OUTBOUND)
    public void replyConfigGet(CommonTopicReceiver receiver, MessageHeaders headers) {
        // 20251219 这里是获取上传临时凭证的接口,稍候分析下是否满足条件,如果可以的话就直接回复临时凭证即可
        CommonTopicResponse<RequestsReply> response = CommonTopicResponse.<RequestsReply>builder()
                .tid(receiver.getTid())
                .bid(receiver.getBid())
@@ -50,4 +86,54 @@
                .build();
        messageSender.publish(headers.get(MqttHeaders.RECEIVED_TOPIC) + TopicConst._REPLY_SUF, response);
    }
    // 验证一下临时凭证是否可用
    public void execMinio(String endpoint,
                          String accessKeyId,
                          String accessKeySecret,
                          String securityToken,
                          String region,
                          String bucketName,
                          String testObjectName) {
        // 1. 替换为你要验证的临时凭证参数(从 getCredentials() 返回的结果中复制)
        try {
            log.info("🔑 正在验证{}临时凭证有效性...", endpoint);
            // 2. 用临时凭证(含 securityToken)初始化 MinIO 客户端
            MinioClient minioClient = MinioClient.builder()
                    .endpoint(endpoint)
//                    .credentials(accessKeyId, accessKeySecret) // 核心:传入 securityToken
                    .credentialsProvider(new StaticProvider(accessKeyId, accessKeySecret, securityToken))
                    .region(region) // 和你配置的 region 一致   us-east-1
                    .build();
            // 3. 执行验证操作:上传一个测试文件(模拟机场上传媒体文件)
            String testContent = "Test securityToken validity";
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(testObjectName)
                            .stream(
                                    new ByteArrayInputStream(testContent.getBytes()),
                                    testContent.getBytes().length,
                                    -1
                            )
                            .build()
            );
            // 4. 验证成功:无异常则 Token 有效
            log.info("✅ securityToken 验证成功!临时凭证可正常操作 MinIO");
            // (可选)额外验证:列出桶内文件,确认上传成功
            log.info("📌 验证文件已上传至:" + bucketName + "/" + testObjectName);
        } catch (MinioException e) {
            // 5. 验证失败:捕获 MinIO 异常,打印具体原因
            log.error("❌ securityToken 验证失败!MinIO 错误:" + e.getMessage());
//            System.err.println("错误代码:" + e.errorCode());
        } catch (InvalidKeyException | NoSuchAlgorithmException e) {
            log.error("❌ 凭证签名错误:" + e.getMessage());
        } catch (Exception e) {
            log.error("❌ 验证过程异常:" + e.getMessage());
        }
    }
}