英文:
How to access User Secret values in Azure Function Isolated Worker service configuration?
问题
在我的函数应用(.NET 7.0,孤立工作者)中,我有一个特定的依赖项,它使用一个API密钥,这需要存储在一个安全存储中。我在本地开发时使用 User Secrets,但我在配置依赖注入服务时如何访问这些秘密值上卡住了:
// secrets.json
{
"apiKey": "1234567890"
}
// Program.cs
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
string apiKey = ???; // 如何在这里访问用户机密?
s.AddScoped<IMyDependency>(sp => new MyDependency(apiKey));
});
.Build();
}
host.Run();
微软有关使用 User Secrets 的指导:
但这些解决方案都没有提供我需要的,即在设置依赖注入时访问用户机密值的方法。相反,推荐的解决方案使配置值本身成为注入的依赖项,这并不适用于我的情况。
我尝试过的方法:
- 使用
Environment.GetEnvironmentVariable
,但它不返回值。 - 使用
builder.AddUserSecrets
添加用户机密配置提供程序。我不知道是否有必要这样做,但即使需要,我仍然不知道如何在设置 DI 时访问配置。
英文:
In my function app (.NET 7.0, Isolated Worker), I have one particular dependency that uses an API key, something that needs to be put in a secret store. I'm using User Secrets for local development, but I'm stuck on how to access those secret values when configuring services for dependency injection:
// secrets.json
{
"apiKey": "1234567890"
}
// Program.cs
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureServices(s =>
{
string apiKey = ???; // how to access user secrets here?
s.AddScoped<IMyDependency>(sp => new MyDependency(apiKey));
});
.Build();
}
host.Run();
There is guidance from Microsoft on using User Secrets:
But neither of these solutions offer what I need, which is a way to access user secret values when setting up dependency injection. Instead, the recommended solution makes the configuration values themselves injected dependencies, which I can't use.
Things I've tried:
- Using
Environment.GetEnvironmentVariable
, which doesn't return a value. - Adding the user secrets configuration provider using
builder.AddUserSecrets
. I don't know whether this is necessary to do, but even if it is, I still don't know how to access the configuration when setting up DI.
答案1
得分: 2
我已经按照你提供的MSDoc中提供的方式来设置了UserSecrets。
我的.csproj
文件:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>****-d46c-****-9752-04-****</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.10.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
Program.cs
文件:
Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureAppConfiguration(con =>
{
con.AddUserSecrets<Program>(optional:true,reloadOnChange:false);
})
.ConfigureServices(s =>
{
var config = s.BuildServiceProvider().GetService<IConfiguration>();
string apiKey = config.GetValue<string>("apiKey");
})
.Build();
host.Run();
[编辑] - 我想澄清并为其他人提供更多信息,虽然这似乎很明显,但AddUserSecrets<Program>()
格式是使其适用于新的Program.cs结构的唯一方式。Startup示例随处可见,而AddUserSecrets()似乎是隐式工作的,不需要指定<T>
,但仅适用于Startup样式。但是,我在互联网上找不到任何关于<Program>
的提及。程序是隐式的,因为现在没有实际的Startup类了。
无论如何,如果不硬编码用户密码,我都无法使用户密码工作,这显然是不可接受的。
输出:
英文:
I have followed the same MSDoc which you have provided to set the UserSecrets.
Thanks @damienbod and SOThread for the code.
My .csproj
file:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<UserSecretsId>****-d46c-****-9752-04-****</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.10.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.7.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="6.0.1" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
Program.cs
file:
Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.Reflection;
var host = new HostBuilder()
.ConfigureFunctionsWorkerDefaults()
.ConfigureAppConfiguration(con =>
{
con.AddUserSecrets<Program>(optional:true,reloadOnChange:false);
})
.ConfigureServices(s =>
{
var config = s.BuildServiceProvider().GetService<IConfiguration>();
string apiKey = config.GetValue<string>("apiKey");
})
.Build();
host.Run();
[edit] - I want to clarify and add for others searching that while it may seem obvious, the AddUserSecrets<Program>() format is the only way to get it to work for the newer Program.cs construct. The Startup example is everywhere, and AddUserSecrets() seems to be implicitly working without specifying <T> but only for the Startup style. But the <Program> mention is NOWHERE that I could find on the Internet. Program is implicit, given there is no actual Startup class anymore.
I could not get User Secrets to work for the life of me without hard coding in the user sercets id, which is obviously not acceptable.
OutPut:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论