IdentityServer4:如何在 Docker 中从证书存储加载签名凭据

11
我们在Windows上成功运行了基于IdentityServer4的STS,其中签名凭据已安装到本地计算机上,.pfx位于个人证书下,.cer位于受信任的人员证书下。然后,我们可以通过其通用名称加载签名凭据,如下所示:
services.AddIdentityServer()
    .AddSigningCredential("CN=CERT_NAME")
    ...

我们现在想要在Docker容器中运行我们的STS实现,但是遇到了以下异常:
Unhandled Exception: System.PlatformNotSupportedException: Unix LocalMachine X509Store is limited to the Root and CertificateAuthority stores.
   at Internal.Cryptography.Pal.StorePal.FromSystemStore(String storeName, StoreLocation storeLocation, OpenFlags openFlags)
   at System.Security.Cryptography.X509Certificates.X509Store.Open(OpenFlags flags)
   at IdentityModel.X509CertificatesFinder.Find(Object findValue, Boolean validOnly)
   at Microsoft.Extensions.DependencyInjection.IdentityServerBuilderExtensionsCrypto.AddSigningCredential(IIdentityServerBuilder builder, String name, StoreLocation location, NameType nameType)

根据上述错误信息和我们在此处使用的AddSigningCredential方法的源代码:https://github.com/IdentityServer/IdentityServer4/blob/ec17672d27f9bed42f9110d73755170ee9265116/src/IdentityServer4/Configuration/DependencyInjection/BuilderExtensions/Crypto.cs#L73,显然我们的问题是IdentityServer4正在寻找本地计算机的个人(“我的”)存储中的证书,但是Unix环境中没有这样的存储,因此会出现错误消息。

因此,我很想知道是否存在一些最佳实践,用于在Docker容器中加载IdentityServer4的签名凭据,如果无法按名称或指纹加载它。唯一的选择是将证书捆绑到我们的应用程序中,然后按文件名加载吗?


1
嗨,Sean,你解决了这个问题吗? - xszaboj
@xszaboj,看起来它是在.NET Core 2中实现的(至少针对CurrentUser\My),参见https://github.com/aspnet/DataProtection/issues/125。这不是LocalMachine\My的情况。 - Bidou
嘿,我在.NET CORE 3.1中遇到了这个错误,有人有解决方案吗? - greektreat
2个回答

6

当您使用Docker容器和IdentityServer时,基本上有两个选项:

  • 将证书添加到容器映像中(COPY certificate.pfx .
  • 将证书挂载到容器中(-v /path/to/certificate.pfx:/certificate.pfx

无论您选择哪个选项,您需要的仅仅是将以下配置代码添加到StartupConfigureServices中。

var identityServerBuilder = services.AddIdentityServer();
/* store configuration and etc. is omitted */
if (_hostingEnvironment.IsDevelopment())
{
    identityServerBuilder.AddDeveloperSigningCredential();
}
else
{
    var certificate = new X509Certificate2("certificate.pfx", "certificate_password");
    identityServerBuilder.AddSigningCredential(certificate);
}

此外,最好从配置、环境变量或密钥存储中读取证书密码。

2
我正在Linux Azure应用服务中托管我的应用程序。我直接从Visual Studio发布到Azure应用服务。如何复制或挂载证书?我仍然在上面的代码段中遇到错误。请帮助解决。 - fingers10

-3

我正在Windows机器上开发,我使用以下代码从存储中获取证书

X509Certificate2 cert = null;

X509Store certStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            certStore.Open(OpenFlags.ReadOnly);

X509Certificate2Collection certCollection = certStore.Certificates.Find(
                        X509FindType.FindByThumbprint,
                        "‎thumbprint",
                        false);
if (certCollection.Count > 0)
    {
        cert = certCollection[0];
        Log.Logger.Information($"Successfully loaded cert from registry: {cert.Thumbprint}");

    }
    if (cert == null) // Fallback
    {
        cert = new X509Certificate2(Path.Combine(_env.ContentRootPath, "certificate.pfx"), "password");
        //Log.Logger.Information($"Falling back to cert from file. Successfully loaded: {cert.Thumbprint}");
    }
    else
    {
        certStore.Dispose();
    }

1
问题是关于Docker,而不是Windows。 - Dave Hillier
2
此答案不适用于此问题。 - fingers10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接