微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用从 Cloud Foundry CredHub 检索到的值配置 IdentityModel 的 ClientCredential

如何解决使用从 Cloud Foundry CredHub 检索到的值配置 IdentityModel 的 ClientCredential

简短的问题陈述:
如何从 Cloud Foundry CredHub 获取价值以在 ConfigureServices(IServiceCollection services) 中使用?

现有条件:
假设我有一个名为 SystemConfig 的类用于保存配置值。我在“开发”阶段使用 json 文件和 dotnet 机密的组合来存储这些值,它们可以通过

检索
services.Configure<SystemConfig>(Configuration.GetSection("GLOBAL"));

在“SIT”阶段,我使用 Pivotal Cloud Foundry 来托管应用程序,并结合使用 configserver - CredHub 来存储配置值。可以通过

Configure(IApplicationBuilder app)内检索来自CredHub的值
var credhub = app.applicationservices.GetService<IOptions<CloudFoundryServicesOptions>>().Value.Services["credhub"].First(x => x.Name.Equals("credhub-instance"));
var sysConfig = app.applicationservices.GetService<IOptions<SystemConfig>>().Value;
sysConfig.SAMPLE_A = credhub.Credentials[nameof(sysConfig.SAMPLE_A)].Value;

当我需要从 IdentityModel.AspNetCore 内的 ConfigureServices 配置访问令牌管理时出现问题:

services.AddAccesstokenManagement(x => 
{
     x.Client.Clients.Add("key_sample",new IdentityModel.Client.ClientCredentialsTokenRequest()
     {
         Address = "sysConfig.SAMPLE_A",ClientId = "taken from sysConfig as well",ClientSecret = "taken from sysConfig as well"
     });
});

方法 AddAccesstokenManagement 只能在 ConfigureService(IServiceCollection services) 内部使用,但同时我还没有来自 CredHub 的值,因为它们是在 Configure(IApplicationBuilder app) 内部检索的。
也不推荐使用 services.BuildServiceProvider(),因为它会创建可能导致意外错误的额外单例服务副本。

所以问题归结为:

  • 我们可以在 ConfigureService(IServiceCollection services) 中检索 CredHub 值吗?
  • 如果不可能,那么我们可以以某种方式在 AddAccesstokenManagement 中设置 Configure(IApplicationBuilder app) 吗?

解决方法

我无法在这里谈论 IdentityModel 的复杂性,乍一看,我没有看到任何让这方面变得容易的东西,但是我有一个解决方案应该可以通过自定义方式使用 Steeltoe Connectors { {1}} 可以定位。

理想情况下,Steeltoe 会自动将这些凭据绑定到 SsoServiceInfo,但目前没有任何内置的东西可以建立这种连接。这段代码将用于在我们完成这里之前检索服务信息:

SsoServiceInfo

为了启用上述代码,我们需要添加一个自定义 services.AddAccessTokenManagement(x => { var creds = Configuration.GetServiceInfo<SsoServiceInfo>("credhub-instance"); x.Client.Clients.Add("key_sample",new IdentityModel.Client.ClientCredentialsTokenRequest() { Address = creds.AuthDomain,ClientId = creds.ClientId,ClientSecret = creds.ClientSecret }); }); ,它可以将您的 credhub 服务实例绑定到 ServiceInfoFactory

SsoServiceInfo

接下来将 using Steeltoe.Connector.Services; using Steeltoe.Extensions.Configuration; public class AuthServiceInfoFactory : ServiceInfoFactory { public AuthServiceInfoFactory() : base(new Tags("credhub"),"credhub") // second param here for url scheme won't actually be used but can't be empty { } public override IServiceInfo Create(Service binding) { // these methods ship with Steeltoe,but look for "client_id" and "client_secret" - customize as desired var clientId = GetClientIdFromCredentials(binding.Credentials); var clientSecret = GetClientSecretFromCredentials(binding.Credentials); var authDomain = GetStringFromCredentials(binding.Credentials,"auth_domain"); return new SsoServiceInfo(binding.Name,clientId,clientSecret,authDomain); } } 属性添加到 ServiceInfoFactoryAssembly 以便 Steeltoe 可以找到您的新工厂:

AssemblyInfo.cs

此外,连接器基于 CloudFoundry 配置提供程序构建,因此请确保您已将其添加到您的主机构建器或配置构建器中,如下所示:

using Steeltoe.Connector;

[assembly: ServiceInfoFactoryAssembly]

最后,请注意,从 v3.0 开始,除非设置了 Host.CreateDefaultBuilder(args) .AddCloudFoundryConfiguration(); ,否则 Steeltoe 将无法识别 vcap:services,因此您可能希望将这种配置格式用于非 CloudFoundry 环境:>

vcap:application

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。