You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成DynamoDB SDK v2遇无效安全令牌异常求助

问题描述

我正在开发一个REST API,使用DynamoDB SDK v2动态指定表名并返回所有记录,需通过Access Key和Secret Key配置DynamoDB客户端,连接AWS云端资源而非本地实例。调用API时抛出异常:

software.amazon.awssdk.services.dynamodb.model.DynamoDbException: The security token included in the request is invalid

我已通过aws configure配置正确的密钥和区域,但问题依旧;且通过Python脚本验证过密钥有效。以下是相关代码:


DynamoDBConfig

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;

@Configuration
public class DynamoDBConfig {

  @Bean
  public DynamoDbClient dynamoDbClient() {
    return DynamoDbClient.builder()
        .region(Region.EU_WEST_2)
        .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(
            "access key",
            "secret key"
        )))
        .build();
  }

}

DynamoDBService

import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import software.amazon.awssdk.services.dynamodb.model.ScanRequest;
import software.amazon.awssdk.services.dynamodb.model.ScanResponse;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class DynamoDBService {

  private final DynamoDbClient dynamoDbClient;

  public DynamoDBService(DynamoDbClient dynamoDbClient) {
    this.dynamoDbClient = dynamoDbClient;
  }

  public ScanResponse getAllItems(String tableName) {
    ScanRequest scanRequest = ScanRequest.builder()
        .tableName(tableName)
        .build();
    return dynamoDbClient.scan(scanRequest);
  }

  public Map<String, AttributeValue> getItem(String tableName, String keyFieldName, String keyFieldValue) {
    GetItemRequest getItemRequest = GetItemRequest.builder()
        .tableName(tableName)
        .key(Map.of(keyFieldName, AttributeValue.builder().s(keyFieldValue).build()))
        .build();
    return dynamoDbClient.getItem(getItemRequest).item();
  }

}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.abc</groupId>
    <artifactId>poc.dynamodb</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>poc.dynamodb</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- AWS SDK for DynamoDB -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>dynamodb</artifactId>
            <version>2.20.26</version>
        </dependency>

        <dependency>
            <groupId>org.springdoc</groupId>
            <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
            <version>2.6.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

排查与解决方案

可能原因

  1. 硬编码密钥错误:代码中占位符"access key"和"secret key"未替换为实际有效密钥,或存在空格、大小写错误。
  2. 凭证优先级冲突:AWS SDK按优先级加载凭证,硬编码凭证可能被环境变量、系统属性或~/.aws/credentials文件中的其他凭证覆盖。
  3. 区域不匹配:代码指定的EU_WEST_2区域与DynamoDB表所在区域不一致,导致请求路由错误引发凭证验证失败。
  4. 权限不足:密钥虽能通过Python脚本验证,但对应的IAM用户无DynamoDB扫描(Scan)权限,被AWS拒绝请求。
  5. SDK版本兼容问题:DynamoDB SDK v2.20.26与Spring Boot 3.2.7存在兼容性问题,导致凭证处理逻辑异常。

解决方案

1. 修正硬编码凭证

将代码中的占位符替换为实际有效的Access Key和Secret Key:

AwsBasicCredentials.create("AKIAXXXXXXXXXXXXXX", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")

2. 统一凭证加载方式

推荐使用AWS SDK默认凭证链加载机制,避免硬编码引发的优先级冲突:
修改DynamoDBConfig,移除硬编码的凭证提供者:

@Bean
public DynamoDbClient dynamoDbClient() {
    return DynamoDbClient.builder()
        .region(Region.EU_WEST_2)
        // 不指定credentialsProvider,自动加载环境变量、~/.aws/credentials等凭证
        .build();
}

确保运行环境中aws configure配置的凭证正确,或设置环境变量AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY。

3. 验证区域一致性

在AWS控制台确认DynamoDB表所在区域,若与代码中的EU_WEST_2不一致,修改代码中的区域参数。

4. 检查IAM权限

为该Access Key对应的IAM用户添加DynamoDB操作权限,示例策略片段:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:Scan",
                "dynamodb:GetItem"
            ],
            "Resource": "arn:aws:dynamodb:eu-west-2:你的AWS账号ID:table/*"
        }
    ]
}

5. 升级SDK版本

将DynamoDB SDK版本升级到与Spring Boot 3.2.7兼容的最新版本,修改pom.xml:

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>dynamodb</artifactId>
    <version>2.25.0</version> <!-- 替换为最新兼容版本 -->
</dependency>

6. 开启日志调试

添加日志配置查看凭证加载细节,定位问题:
在application.properties中添加:

logging.level.software.amazon.awssdk.auth=DEBUG
logging.level.software.amazon.awssdk.request=DEBUG

通过日志确认实际使用的凭证和请求信息,排查加载错误。

内容的提问来源于stack exchange,提问作者anonymous

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:13:17