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

部署至Google Run的ASP.Net Core Web API加载密钥的最优方案

优雅整合Google Secret Manager与.NET Core配置系统

把配置读取逻辑混在业务服务里确实别扭,好在Google官方提供了.NET配置扩展,能让你像用本地UserSecrets一样直接从Secret Manager加载配置,完美匹配你想要的简洁方案。

步骤1:安装NuGet扩展包

首先安装Google官方的配置扩展,它能把Secret Manager的密钥无缝接入.NET的Configuration体系:

dotnet add package Google.Cloud.SecretManager.Configuration

步骤2:在Program.cs中配置Secret Manager加载

只需要在构建Configuration时添加一行代码,就能让系统自动从Secret Manager读取密钥,同时保留本地配置(UserSecrets/appsettings)的优先级:

var builder = WebApplication.CreateBuilder(args);

// 添加Secret Manager配置源,本地配置优先,本地无对应配置时自动从Secret Manager加载
builder.Configuration.AddSecretManager();

// 接下来和本地开发完全一致的配置方式
builder.Services.Configure<GameDatabaseSettings>(
    builder.Configuration.GetSection("GameDatabase"));
builder.Services.AddSingleton<GamesService>();

// ...其他中间件与服务配置
var app = builder.Build();
// ...后续启动代码

步骤3:调整Secret Manager的密钥命名

为了让.NET配置系统正确识别分层配置节,需要在Secret Manager中使用冒号分隔的密钥名称,对应你的GameDatabaseSettings结构:

  • 密钥名称:GameDatabase:ConnectionString → 对应配置节GameDatabase.ConnectionString
  • 密钥名称:GameDatabase:DatabaseName → 对应配置节GameDatabase.DatabaseName
  • 密钥名称:GameDatabase:GamesCollectionName → 对应配置节GameDatabase.GamesCollectionName

这样Configuration系统会自动把这些密钥合并到GameDatabase配置节下,和你本地的UserSecrets结构完全对齐。

步骤4:简化GamesService代码

现在可以彻底删掉服务里手动读取Secret Manager的冗余逻辑,直接依赖注入IOptions<GameDatabaseSettings>即可,和本地开发时的代码完全一致:

using Microsoft.Extensions.Options;
using MongoDB.Driver;

namespace my_api.DataPersistence;

public class GamesService
{
    private readonly IMongoCollection<Game> _gamesCollection;

    public GamesService(IOptions<GameDatabaseSettings> gameDatabaseSettings)
    {
        var settings = gameDatabaseSettings.Value;
        var mongoClient = new MongoClient(settings.ConnectionString);
        var mongoDatabase = mongoClient.GetDatabase(settings.DatabaseName);
        _gamesCollection = mongoDatabase.GetCollection<Game>(settings.GamesCollectionName);
    }

    public bool GameCollectionExists => _gamesCollection != null;

    public async Task<List<Game>> GetAsync() =>
        await _gamesCollection.Find(_ => true).ToListAsync();

    public async Task<Game?> GetAsync(string id) =>
        await _gamesCollection.Find(x => x.Id == id).FirstOrDefaultAsync();

    public async Task CreateAsync(Game newGame) =>
        await _gamesCollection.InsertOneAsync(newGame);

    public async Task UpdateAsync(string id, Game updatedGame) =>
        await _gamesCollection.ReplaceOneAsync(x => x.Id == id, updatedGame);

    public async Task RemoveAsync(string id) =>
        await _gamesCollection.DeleteOneAsync(x => x.Id == id);
}

步骤5:配置Google Run服务账号权限

确保你的Google Run服务账号拥有Secret Manager Secret Accessor角色,这样应用才能访问Secret Manager里的密钥:

  1. 打开Google Cloud控制台,找到目标Google Run服务
  2. 进入「权限」标签,添加服务账号(默认是[项目编号]-compute@developer.gserviceaccount.com)
  3. 为该账号分配Secret Manager Secret Accessor角色

配置优先级说明

  • 本地开发时,系统优先读取UserSecrets/appsettings里的配置,不会触发Secret Manager调用
  • 部署到Google Run后,本地配置不存在时,自动从Secret Manager加载对应密钥
  • 如果需要临时覆盖Secret Manager配置(比如测试环境),可以通过Google Run的环境变量设置,环境变量优先级高于Secret Manager

这样整个配置逻辑完全解耦,业务服务不需要关心配置来源,只依赖.NET的标准配置系统即可,完全实现了你想要的简洁方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 00:30:56