ProvisioningDeviceClient Create()仅在Azure中的托管应用程序中失败

时间:2019-03-19 11:59:45

标签: asp.net-core azure-web-app-service azure-iot-hub

在Azure中运行ASP.NET Core 2.2 Web App API。在本地运行代码。将代码托管在Azure中时失败。 Nuget软件包的版本为1.2.2(Microsoft.Azure.Devices.Provisioning.Client)。

出于可读性考虑,我删除了日志语句:

using (var securityProvider = new SecurityProviderX509Certificate(pfxDeviceContents.certificate, pfxDeviceContents.collection))
                    {
                        using (var transport = new ProvisioningTransportHandlerHttp())
                        {
                            var globalendp = _configuration["ProvisioningEndpoint"];
                            var scope = _configuration["DpsScopeId"];

                            var provClient = ProvisioningDeviceClient.Create(globalendp, scope, securityProvider, transport);
....

引发的异常是:

  

Internal.Cryptography.CryptoThrowHelper + WindowsCryptographicException:访问被拒绝      在Internal.Cryptography.Pal.StorePal.Add(ICertificatePal证书)      在System.Security.Cryptography.X509Certificates.X509Store.Add(X509Certificate2证书)      在Microsoft.Azure.Devices.Provisioning.Client.CertificateInstaller.EnsureChainIsInstalled(X509Certificate2Collection证书)      在Microsoft.Azure.Devices.Provisioning.Client.ProvisioningDeviceClient.Create(字符串globalDeviceEndpoint,字符串idScope,SecurityProvider securityProvider,ProvisioningTransportHandler传输)

到目前为止,我取得了与托管应用程序完全相同的证书,该证书在托管应用程序中失败,并使用同一应用程序的本地实例运行了该证书。因此,证书本身不是问题。我是否可以收集其他信息来帮助解决此问题?任何人都可以确认在Azure中使用此类的工作正常吗?

1 个答案:

答案 0 :(得分:1)

简而言之,不支持此功能。下面的答案可能会节省一些人试图弄清楚这项工作的时间

Microsoft的技术支持答案如下:

症状

ProvisioningDeviceClient类在Azure中不起作用

原因

该错误的原因是该代码正在尝试写入中间CA。

https://www.fuget.org/packages/Microsoft.Azure.Devices.Provisioning.Client/1.2.2/lib/netstandard2.0/Microsoft.Azure.Devices.Provisioning.Client.dll/Microsoft.Azure.Devices.Provisioning.Client/CertificateInstaller?code=true#M%3AMicrosoft.Azure.Devices.Provisioning.Client.CertificateInstaller.EnsureChainIsInstalled%28System.Security.Cryptography.X509Certificates.X509Certificate2Collection%29

        _installedCertificates = new HashSet<string>();
        _lock = new object();
        try {
            using (X509Store x509Store = new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)) {
                x509Store.Open(OpenFlags.ReadOnly);
                X509Certificate2Enumerator enumerator = x509Store.Certificates.GetEnumerator();
                while (enumerator.MoveNext()) {
                    X509Certificate2 current = enumerator.Current;
                    _installedCertificates.Add(current.Thumbprint);
                }
            }
        } catch (Exception ex) {
            if (Logging.IsEnabled)
                Logging.Error(null, FormattableStringFactory.Create("{0} failed to read store: {1}.", "CertificateInstaller", ex), ".cctor");
        }

https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.storename?view=netframework-4.7.2

证书颁发机构 3 用于中间证书颁发机构(CA)的X.509证书存储。

沙箱通常旨在限制对Windows共享组件的访问。不幸的是,Windows的许多核心组件已被设计为共享组件:注册表,加密和图形子系统,等等。

请参考以下文档,其中有更详细的说明。 https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#general-sandbox-restrictions

解决方案

另一种选择是使用Windows容器,但是当前处于预览状态。 https://azure.microsoft.com/en-us/blog/announcing-the-public-preview-of-windows-container-support-in-azure-app-service/

AppService无法针对中级商店打开以安装证书链。安装中间证书链的唯一方法是上载包含该证书链的证书。如果webapp运行VM,那么您将拥有完全的控制权,并且可以执行所需的操作。如果运行云服务,则可以在启动任务中完成操作。借助App Service,您可以减少设计方面的控制。

https://docs.microsoft.com/en-us/azure/app-service/overview-compare

您对DPS代码完全正确,需要本地证书存储。如您所述,它已添加到DPS SDK中,该DPS SDK是作为替代解决方案而设计的。