Хотели бы подключиться к разным локальным хранилищам, совместимым с S3, в одном - PullRequest
0 голосов
/ 09 июля 2020

В настоящее время мы подключаемся к корзине наших команд в нашем локальном хранилище, совместимом с S3.

Класс конфигурации:

@Configuration
public class S3Config {

@Value("${aws.access_key_id}")
private String awsId;
@Value("${aws.secret_access_key}")
private String awsKey;
@Value("${s3.endpoint}")
private String endpoint;

@Value("${s3.keystorePD}")
private String keystorePD;

@Value("${s3.jksFile}")
private String jksFile;


private static final Logger log = LoggerFactory.getLogger(S3Config.class);
@PostConstruct
public void init()
{

    log.info("Initializing SSL Configuration for S3 bucket");
    System.setProperty(ApplicationConstants.KEY_STORE_TYPE,"jks");
    System.setProperty(ApplicationConstants.TRUST_STORE_TYPE,"jks");
    System.setProperty(ApplicationConstants.KEY_STORE_PROPERTY,Thread.currentThread().getContextClassLoader().getResource(jksFile).getFile());
    System.setProperty(ApplicationConstants.TRUST_STORE_PROPERTY,Thread.currentThread().getContextClassLoader().getResource(jksFile).getFile());
    System.setProperty(ApplicationConstants.KEY_STORE_PD,keystorePD);
    System.setProperty(ApplicationConstants.TRUST_STORE_PD,keystorePD);
    log.info("Successfully initialized SSL Configuration for S3 bucket");
}

@Bean
public AmazonS3 s3client() {
    log.info("Initializing the S3 client");
    AmazonS3 s3Client = null;
    BasicAWSCredentials awsCreds = new BasicAWSCredentials(awsId,
            awsKey);
    s3Client = new AmazonS3Client(awsCreds);
    s3Client.setEndpoint(endpoint);
    return s3Client;
}

Использование:

@Autowired
AmazonS3 s3Client;

public void uploadFile(File file, String targetLocation, String bucketName) {
    log.info("converted file size : " + file.getTotalSpace());
    log.info("bucketName : " + bucketName);
    log.info("targetLocation : " + targetLocation);
    s3Client.putObject(bucketName, targetLocation, file);
}

Мое требование - создавать клиента динамически для каждого входящего запроса. Итак, допустим, если команда A передана, для подключения к хранилищу используется конфигурация s3 с файлом jks команды A.

Я использую:

  • Spring Boot v2.3.1. ВЫПУСК
  • aws -sdk v1.11.560
  • Открыть JDK v11.0.1

Как этого добиться?

ОБНОВЛЕНИЕ:

У меня будут файлы jks, access_keys, access_ids с самого начала приложения.

1 Ответ

0 голосов
/ 09 июля 2020

В этой ситуации есть две уникальные проблемы:

  1. Использование несистемных свойств для предоставления материала шифрования
  2. Переключение (и создание, если необходимо) учетных данных для каждого запроса.

Следующий план решения решит обе проблемы. Вместо этого он использует StaticEncryptionMaterialsProvider, чтобы избежать зависимости от свойств системы. чтобы решить вторую проблему, S3ClientResolver использует область REQUEST с proxyMode как TARGET_CLASS, чтобы обеспечить правильную работу проводки в контексте Spring в этом случае. .yml, как показано ниже

teams:
  one:
    awsId: abc
    awsKey: abc
    endpoint: https://example.com
    keystorePD: onejskpass
    jksFile: one.jks
  two:
    awsId: abc2
    awsKey: abc2
    endpoint: https://example.com
    keystorePD: twojskpass
    jksFile: two.jks

После этого ваш код будет выглядеть следующим образом

@Autowired
private S3ClientResolver resolver;

public void uploadFile(File file, String targetLocation, String bucketName) {
    log.info("converted file size : " + file.getTotalSpace());
    log.info("bucketName : " + bucketName);
    log.info("targetLocation : " + targetLocation);
    resolver.getClient().putObject(bucketName, targetLocation, file);
}

Пожалуйста, настройте его в соответствии с вашими собственными средами. Я быстро извлек эти фрагменты из одной из своих прошлых аналогичных работ. Я оставил многие элементы в приведенном выше фрагменте в качестве комментариев. Пожалуйста, заполните go и настройте его в соответствии с вашими вариантами использования.

[Edit - 15 июля 2020]

jackfr0st, logi c генерации ключевой пары работает, я только что проверил это с следующая автономная программа, которая является точной копией того, что упомянуто выше, с исправлением оператора return (который отсутствовал ранее) в строке new KeyPair(publicKey, (PrivateKey) key) - для этой цели я создал fre sh keystore (testjks.jks), используя следующую команду - keytool -genkey -alias mydomain -keyalg RSA -keystore keystore.jks -keysize 2048

import java.io.FileInputStream;
import java.security.*;
import java.security.cert.Certificate;

public class ExtractKeypair {
    public static void main(String[] args)  throws Exception {
        KeyPair kp = generateKeypair("testjks.jks");
    }

    public static KeyPair generateKeypair(String file) throws Exception {
        FileInputStream is = new FileInputStream(Thread.currentThread().getContextClassLoader()
                .getResource(file).getFile());
        KeyStore keystore = KeyStore.getInstance("jks");
        keystore.load(is, "password".toCharArray());

        // the only key in your JKS must have this alias
        // you may also add the alias as another property in your configuration instead
        String alias = "mydomain";

        Key key = keystore.getKey(alias, "password".toCharArray());
        if (key instanceof PrivateKey) {
            Certificate cert = keystore.getCertificate(alias);
            PublicKey publicKey = cert.getPublicKey();
            return new KeyPair(publicKey, (PrivateKey) key);
        }
        throw new RuntimeException("Invalid key");
    }
}

Если вы все еще сталкиваетесь с проблемой, я предлагаю посмотреть на возвращенный ресурс (Thread.currentThread().getContextClassLoader().getResource(file).getFile()), так как это единственная переменная, которая может вызвать проблему, если она неверна. Я тестировал вышеуказанную программу с помощью oracle jdk 8.

...