gpt4 book ai didi

java - 无法使用 AWS 安全 token 找到请求目标的有效证书路径

转载 作者:行者123 更新时间:2023-12-03 08:34:26 25 4
gpt4 key购买 nike

我正在尝试实现以下 AWS 文章中介绍的解决方案:


所以我做了接下来的步骤:

  1. 创建本地 keystore :

    keystore winpty openssl pkcs12 -export -in eeb81a0eb6-certificate.pem.crt -inkey eeb81a0eb6-private.pem.key -name myname -out my.p12 -password pass:mypass

    keytool -importkeystore -destkeystore mykeystore.jks -srckeystore my.p12 -srcstoretype PKCS12 -deststorepass mypass -srcstorepass mypass

  2. 创建本地信任库:

    keytool -keystore my_ca.jks -alias myalias -import -file AmazonRootCA1.pem

  3. 我的代码:

public class AWSSessionCredentialsProviderImpl implements AWSSessionCredentialsProvider  {

private static final Logger LOGGER = LogManager.getLogger(AWSSessionCredentialsProviderImpl.class.getName());

private final Gson gson = new Gson();

private SdkHttpClient client;
private HttpExecuteRequest request;
private String awsAccessKeyId;
private String awsSecretAccessKeyId;
private String awsSessionToken;

public void init(String clientId) throws IOException, URISyntaxException {
System.setProperty("javax.net.ssl.trustStore", Configuration.KEYSTOREPATH_CA.toAbsolutePath().toString());
System.setProperty("javax.net.ssl.trustStoreType", "jks");

try {
System.setProperty("javax.net.ssl.trustStorePassword", new String(Files.readAllBytes(Configuration.KEYSTOREPATH_CA_PASS)));
} catch (IOException e) {
throw new IOException("Read password of trust store is failed", e);
}


System.setProperty("javax.net.ssl.keyStore", Configuration.KEYSTOREPATH.toAbsolutePath().toString());
System.setProperty("javax.net.ssl.keyStoreType", "jks");

try {
System.setProperty("javax.net.ssl.keyStorePassword", new String(Files.readAllBytes(Configuration.KEYSTOREPATH_PASS)));
} catch (IOException e) {
throw new IOException("Read password of key store is failed", e);
}

client = ApacheHttpClient.builder().build();

SdkHttpRequest httpRequest;
try {
httpRequest = SdkHttpFullRequest.builder()
.method(SdkHttpMethod.GET)
.uri(new URI(Configuration.CLIENT_ENDPOINT))
.putHeader("x-amzn-iot-thingname", clientId)
.build();
} catch (URISyntaxException e) {
throw new URISyntaxException(Configuration.CLIENT_ENDPOINT, "Building URI from client endpoint is failed");
}

request = HttpExecuteRequest.builder()
.request(httpRequest)
.build();
try {
setCredentials();
} catch (IOException e) {
throw new IOException("Set temporary credentials is failed", e);
}
}

@Override
public void refresh() {
try {
setCredentials();
} catch (IOException e) {
LOGGER.error("Refresh session credentials is failed", e);
}
}

@Override
public AWSSessionCredentials getCredentials() {
return new BasicSessionCredentials(awsAccessKeyId, awsSecretAccessKeyId, awsSessionToken);
}

private void setCredentials() throws IOException {
HttpExecuteResponse response = client.prepareRequest(request).call();
String credStr = IoUtils.toUtf8String(response.responseBody().get());

CredentialsJson credJson = gson.fromJson(credStr, CredentialsJson.class);
awsAccessKeyId = credJson.credentials.accessKeyId;
awsSecretAccessKeyId = credJson.credentials.secretAccessKey;
awsSessionToken = credJson.credentials.sessionToken;
}
}

  • 因此,我成功获得了临时凭据,但是当我使用它们时:
  • AWSSessionCredentialsProviderImpl credentialsProvider = new AWSSessionCredentialsProviderImpl();
    credentialsProvider.init("someid");

    s3Client = AmazonS3ClientBuilder.standard()
    .withRegion(region)
    .withCredentials(credentialsProvider)
    .build();

    s3Client.putObject(request);

    我收到以下异常:

    Caused by:
    sun.security.provider.certpath.SunCertPathBuilderException:unable to find valid certification path to requested target

    如果我能够成功获取临时凭据,我不明白为什么会出现此异常。

    最佳答案

    这个问题可能与很多事情有关。

    您的 Java 程序很可能无法与远程对等点建立信任关系,这可能是因为 AWS CA 不是预配置的 JVM 可信 CA 之一。

    我认为解决该问题的最佳方法是将您已有的 SdkHttpClient 也传递给 S3 客户端。

    请注意,在您的示例代码中,您使用的是 AWS Java SDK 版本 1 类 AmazonS3ClientBuilder,同时其余代码使用的是 AWS SDK v2。

    也许您可以将代码更新为 latest version of the S3Client并尝试这样的事情:

    System.setProperty("javax.net.ssl.trustStore", Configuration.KEYSTOREPATH_CA.toAbsolutePath().toString());
    System.setProperty("javax.net.ssl.trustStoreType", "jks");

    try {
    System.setProperty("javax.net.ssl.trustStorePassword", new String(Files.readAllBytes(Configuration.KEYSTOREPATH_CA_PASS)));
    } catch (IOException e) {
    throw new IOException("Read password of trust store is failed", e);
    }


    System.setProperty("javax.net.ssl.keyStore", Configuration.KEYSTOREPATH.toAbsolutePath().toString());
    System.setProperty("javax.net.ssl.keyStoreType", "jks");

    try {
    System.setProperty("javax.net.ssl.keyStorePassword", new String(Files.readAllBytes(Configuration.KEYSTOREPATH_PASS)));
    } catch (IOException e) {
    throw new IOException("Read password of key store is failed", e);
    }

    SdkHttpClient client = ApacheHttpClient.builder().build();

    // The idea is reuse the configured HTTP client, modify it as per your needs
    AWSSessionCredentialsProviderImpl credentialsProvider = new AWSSessionCredentialsProviderImpl(client);
    credentialsProvider.init("someid");

    S3Client s3 = S3Client.builder()
    .httpClient(client)
    .region(region)
    .credentialsProvider(credentialsProvider)
    .build();

    请确保您的信任存储区包含实际的 SSL 证书。您有AWS的根CA证书,但可能不是与实际服务对应的。

    如有必要,您可以通过以下方式获取服务 SSL 证书:

    openssl s_client -connect s3.us-west-1.amazonaws.com:443

    请根据您所在的地区更改命令。您需要从响应中提取 PEM 内容。

    如答案评论中所示,另一种替代方法可以取消设置在调用 S3Client 之前获取凭据时建立的 System 属性:

    System.clearProperty("javax.net.ssl.trustStore");
    System.clearProperty("javax.net.ssl.trustStorePassword");
    System.clearProperty("javax.net.ssl.trustStoreType");

    它将为 AWS SDK 提供调用 S3 的全新环境。

    关于java - 无法使用 AWS 安全 token 找到请求目标的有效证书路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64347224/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com