部署后使用连接字符串configSource属性以及Azure App Service环境连接字符串

时间:2016-11-23 14:50:55

标签: asp.net .net azure web-config azure-web-sites

我试图关注Best practices for private config data and connection strings in configuration in ASP.NET and AzureBest practices for deploying passwords and other sensitive data to ASP.NET and Azure App Service

我采取的步骤:

我有一个带有常规web.config文件的ASP.NET 4.6 Web App。我为我的秘密创建了两个文件:Web.Secrets.AppSettings.configWeb.Secrets.ConnectionString.config,根据教程将相应的秘密放入其中并修改根web.config所以它看起来像这样:

<configuration>
  <appSettings file="Web.Secrets.AppSettings.config">
  </appSettings>
  <connectionStrings configSource="Web.Secrets.ConnectionStrings.config">
  </connectionStrings>
  <!--...-->
</configuration>

然后我在Azure门户中创建了一个新的 Azure App Service ,打开了它的应用程序设置,并将秘密添加到相应的部分( App设置连接字符串)。

之后,我将我的Web应用程序部署到此Azure应用服务,之后在启动时获得了黄色死亡屏幕,并显示以下消息:

  

&#39; /&#39;中的服务器错误应用

     

配置错误

     

说明:处理期间发生错误   服务此请求所需的配置文件。请查看   以下具体错误详细信息并修改您的配置文件   适当。

     

分析程序错误消息:无法打开configSource文件   &#39; Web.Secrets.ConnectionStrings.config&#39;

     

来源错误

     

服务器上发生应用程序错误。当前的自定义错误   此应用程序的设置会阻止应用程序的详细信息   远程查看错误(出于安全原因)。它可能,   但是,可以在本地服务器计算机上运行的浏览器查看。

     

源文件:D:\ home \ site \ wwwroot \ web.config行:8

     

版本信息:Microsoft .NET Framework版本:4.0.30319;   ASP.NET版本:4.6.1590.0

当然Web.Secrets.ConnectionStrings.configWeb.Secrets.AppSettings.config不会被复制,而且正是我所需要的。相应的秘密应该从环境变量中获取。

错误页面的HTML Source中有一个堆栈跟踪:

[ConfigurationErrorsException]: Unable to open configSource file 'Web.Secrets.ConnectionStrings.config'. (D:\home\site\wwwroot\web.config line 8)
   at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
   at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
   at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
   at System.Web.Configuration.HttpConfigurationSystem.GetApplicationSection(String sectionName)
   at System.Web.Configuration.HttpConfigurationSystem.GetSection(String sectionName)
   at System.Web.Configuration.HttpConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String configKey)
   at System.Configuration.ConfigurationManager.GetSection(String sectionName)
   at System.Configuration.ConfigurationManager.get_ConnectionStrings()
   at EnvSettings.SettingsProcessor.SetConnectionString(String name, String connString, String providerName)
   at EnvSettings.SettingsProcessor.Start()
[InvalidOperationException]: The pre-application start initialization method Start on type EnvSettings.SettingsProcessor threw an exception with the following error message: Unable to open configSource file 'Web.Secrets.ConnectionStrings.config'. (D:\home\site\wwwroot\web.config line 8).
   at System.Web.Compilation.BuildManager.InvokePreStartInitMethodsCore(ICollection`1 methods, Func`1 setHostingEnvironmentCultures)
   at System.Web.Compilation.BuildManager.InvokePreStartInitMethods(ICollection`1 methods)
   at System.Web.Compilation.BuildManager.CallPreStartInitMethods(String preStartInitListPath, Boolean& isRefAssemblyLoaded)
   at System.Web.Compilation.BuildManager.ExecutePreAppStart()
   at System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException)
[HttpException]: The pre-application start initialization method Start on type EnvSettings.SettingsProc

我做错了什么?或者它只是Azure中的一个错误?

重要说明

  • 应用程序在启动时失败。 我甚至无法触摸任何与配置文件相关的内容。
  • 如果我从Azure App Service的“应用程序设置”中删除连接字符串部分中的连接字符串,则应用程序启动正常。如果我收回它,应用程序会再次启动失败。 这很奇怪!考虑一下!有连接字符串 - 失败,没有连接字符串 - 很好。
  • 当我在本地运行应用程序并且没有Web.Secrets.ConnectionStrings.config文件时,该应用程序运行正常。只有在Azure App Service中部署时,应用程序才会失败。 因此,问题是Azure App Service特定。
  • 即使使用一个简单的空ASP.NET Web应用程序项目,它也在被复制。
  • 关于appSettings的部分工作正常,只有connectionStrings的部分失败。

默认Azure应用服务环境变量:

WEBSITE_NODE_DEFAULT_VERSION: 4.4.7

可能的解决方法:

配置转换可用于删除Web.config中的相应属性。例如,Web.Release.config的外观如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings xdt:Transform="RemoveAttributes(configSource)"/>
  <system.web>
    <compilation xdt:Transform="RemoveAttributes(debug)" />
  </system.web>
</configuration>

1 个答案:

答案 0 :(得分:3)

我调查了这一点,我的结论是,这不是Azure问题,而是配置系统使用连接字符串configSource的行为方式。具体来说,行为是当您指定此类指令时,该文件必须存在,或者任何访问连接字符串的尝试都会爆炸。例如在Azure之外,设置指向缺少configSource的web.config并运行:

ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings["foo"];

它会以同样的方式爆炸(Unable to open configSource file 'Web.Secrets.ConnectionStrings.config'.)。

有趣的是,因为使用App Settings,当文件丢失时,它可以简单地忽略file指令。

但这些都不是特定于Azure的。它只是.NET框架配置系统行为。我创建了一个简单的控制台应用程序,它演示了:https://github.com/davidebbo-test/ConsoleAppWithMissingConfigSourceFile

你需要抽取属性(正如你所示),或者部署一个虚拟文件以保持它的快乐。