У меня есть код для загрузки сертификата X509 из моего файла appsettings.json вместе с паролем (pfx-файл в кодировке base64), который выглядит следующим образом:
public static X509Certificate2 LoadSsoCertificate(IConfiguration config)
{
//this should be a self-signed PFX certificate with the private key included.
var certificateText = config["SSO:x509Certificate"];
//this should be the password to open/ read the certificate.
var certificatePassword = config["SSO:SecretKeyPassphrase"];
var certificateBytes = Convert.FromBase64String(certificateText);
var cert = new X509Certificate2(certificateBytes, certificatePassword);
return cert;
}
Это прекрасно работает при локальном тестировании,но при развертывании в службе приложений Azure я получил следующее загадочное исключение:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The specified network password is not correct
at Internal.Cryptography.Pal.CertificatePal.FilterPFXStore(Byte[] rawData, SafePasswordHandle password, PfxCertStoreFlags pfxCertStoreFlags)
at Internal.Cryptography.Pal.CertificatePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password)
at MyCompany.AuthenticationServices.Core.Configuration.SingleSignOn.LoadSsoCertificate(IConfiguration config) in d:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\SingleSignOn.cs:line 43
at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(Saml2Options options) in d:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 51
at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(String name, Saml2Options options) in d:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 78
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Sustainsys.Saml2.AspNetCore2.Saml2Handler.<>c__DisplayClass6_0.<InitializeAsync>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Sustainsys.Saml2.AspNetCore2.Saml2Handler.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at MyCompany.SoaToolkit.LoggingContext.AspNetCore.Middleware.Configuration.<>c.<<UseLoggingContextRequests>b__0_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
Он говорит, что указанный «сетевой» пароль неверен, но это тот же пароль, который работает локально, поэтому я не могупредставьте, что проблема на самом деле в пароле, и он не должен пытаться использовать «сеть». Кто-нибудь может пролить некоторый свет на то, в чем здесь проблема, и предложить предложения о том, как заставить этот относительно простой код работать?
ОБНОВЛЕНИЕ
Основано на комментариях @ Crypt32Я создал новый сертификат непосредственно в Azure и сохранил его в виде PFX на своем локальном рабочем столе, затем закодировал его в Base64 и включил в свой файл appsettings. Опять же, это работало хорошо локально, но когда я развернул в Azure, я получил похожее, но также мистифицирующее исключение:
Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: The system cannot find the file specified
at Internal.Cryptography.Pal.StorePal.FromBlobOrFile(Byte[] rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
at System.Security.Cryptography.X509Certificates.X509Certificate2Collection.Import(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
at MyCompany.AuthenticationServices.Core.Configuration.SingleSignOn.LoadSsoCertificate(IConfiguration config) in D:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\SingleSignOn.cs:line 40
at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(Saml2Options options) in D:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 51
at MyCompany.AuthenticationServices.Core.Configuration.ConfigureMultiTenantSaml2Options.Configure(String name, Saml2Options options) in D:\a\1\s\MyCompany.AuthenticationServices.Core\Configuration\ConfigureMultiTenantSaml2Options.cs:line 78
at Microsoft.Extensions.Options.OptionsFactory`1.Create(String name)
at Sustainsys.Saml2.AspNetCore2.Saml2Handler.<>c__DisplayClass6_0.<InitializeAsync>b__0()
at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
--- End of stack trace from previous location where exception was thrown ---
at System.Lazy`1.CreateValue()
at Microsoft.Extensions.Options.OptionsCache`1.GetOrAdd(String name, Func`1 createOptions)
at Sustainsys.Saml2.AspNetCore2.Saml2Handler.InitializeAsync(AuthenticationScheme scheme, HttpContext context)
at Microsoft.AspNetCore.Authentication.AuthenticationHandlerProvider.GetHandlerAsync(HttpContext context, String authenticationScheme)
at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
at MyCompany.SoaToolkit.LoggingContext.AspNetCore.Middleware.Configuration.<>c.<<UseLoggingContextRequests>b__0_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Server.IISIntegration.IISMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)