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

本地运行AWS Lambda时遭遇安全令牌无效错误求助

解决本地调试Java Lambda时SecretsManager安全令牌无效问题

错误原因分析

你遇到的UnrecognizedClientException(安全令牌无效),核心问题在于本地运行Lambda时AWS客户端无法获取有效身份凭证,同时代码存在SDK版本混用、区域配置缺失、JDBC URL格式错误等问题:

  • AWS SDK v1和v2类混用,导致区域配置不生效
  • SecretsManager客户端未指定目标区域(us-east-2),默认区域与凭证权限范围不匹配
  • 本地未配置拥有SecretsManager访问权限的AWS凭证
  • JDBC URL格式不符合PostgreSQL连接要求

分步解决方案

1. 统一AWS SDK版本,修复区域与JDBC配置

代码中同时使用了AWS SDK v1和v2的区域类,导致区域配置失效,同时JDBC URL缺少必要的协议前缀、端口和数据库名。修改后的代码如下:

package handlers;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.GetSecretValueRequest;
import com.amazonaws.services.secretsmanager.model.GetSecretValueResult;
import com.amazonaws.regions.Regions;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class StoreDataLambda implements RequestStreamHandler {

    // 修复JDBC URL:添加协议前缀、默认端口5432、数据库名(需替换为你的实际数据库名)
    private static final String DB_URL = "jdbc:postgresql://blog-post-db.cb61nkakvvkt.us-east-2.rds.amazonaws.com:5432/blog_db";
    
    @Override
    public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        Connection connection = null;
        PreparedStatement statement = null;

        try {
            // 指定us-east-2区域构建SecretsManager客户端
            AWSSecretsManager secretsManager = AWSSecretsManagerClientBuilder.standard()
                    .withRegion(Regions.US_EAST_2)
                    .build();
            
            String secretName = "prod/blogDB/dbUserPass";

            GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest()
                    .withSecretId(secretName);

            GetSecretValueResult secretValueResult = secretsManager.getSecretValue(getSecretValueRequest);

            // 解析凭证JSON
            String secret = secretValueResult.getSecretString();
            JsonNode secretJson = mapper.readTree(secret);
            String dbUsername = secretJson.get("username").asText();
            String dbPassword = secretJson.get("password").asText();

            // 建立数据库连接
            connection = DriverManager.getConnection(DB_URL, dbUsername, dbPassword);
            
            // 解析输入事件
            JsonNode jsonInput = mapper.readTree(input);
            String title = jsonInput.get("title").asText();
            String content = jsonInput.get("content").asText();

            // 执行插入操作
            String sql = "INSERT INTO blog_page.blog_post (title, content) VALUES (?, ?)";
            statement = connection.prepareStatement(sql);
            statement.setString(1, title);
            statement.setString(2, content);
            statement.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 统一关闭资源
            try {
                if (statement != null) statement.close();
                if (connection != null && !connection.isClosed()) connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

2. 配置本地AWS凭证

本地运行Lambda需要拥有对应权限的AWS凭证:

  • 在本地创建~/.aws/credentials(Linux/macOS)或C:\Users\<你的用户名>\.aws\credentials(Windows)文件,内容格式:
[default]
aws_access_key_id = 你的IAM用户访问密钥ID
aws_secret_access_key = 你的IAM用户私有访问密钥
  • 确保该IAM用户拥有SecretsManagerReadWritePolicy权限(与CloudFormation配置一致)

3. 优化CloudFormation模板

模板中RDSConnectPolicy的Region参数无需手动指定,SAM会自动匹配部署区域,修改后模板:

AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: Handler for blog post input

Resources:
  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: MyLambdaFunction
      Handler: handlers.StoreDataLambda::handleRequest
      Runtime: java17
      MemorySize: 512
      CodeUri: target/BlogInputLambda-1.0-SNAPSHOT-shaded.jar
      Policies:
        - SecretsManagerReadWritePolicy:
            SecretName: prod/blogDB/dbUserPass
        - RDSConnectPolicy:
            DBInstanceIdentifier: blog-post-db

4. 本地调试建议

使用AWS SAM CLI进行本地调试,确保环境与云端一致:

  1. 安装SAM CLI
  2. 创建测试事件文件event.json,内容示例:
{"title":"测试标题","content":"测试内容"}
  1. 执行调试命令:
sam local invoke MyLambdaFunction --event event.json

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:34:59