asp.net - 使用连接字符串 configSource 属性以及 Azure 应用服务环境连接字符串时,部署后启动失败

标签 asp.net .net azure web-config azure-web-app-service

我正在尝试关注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 应用程序。我为我的secret创建了两个文件:Web.Secrets.AppSettings.configWeb.Secrets.ConnectionString.config,根据教程将相应的secret放入其中并修改root web.config 所以它看起来像这样:

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

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

之后,我将 Web 应用程序部署到此 Azure 应用程序服务,然后在启动时出现蓝屏死机,并显示以下消息:

Server Error in '/' Application.

Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Unable to open configSource file 'Web.Secrets.ConnectionStrings.config'.

Source Error:

An application error occurred on the server. The current custom error settings for this application prevent the details of the application error from being viewed remotely (for security reasons). It could, however, be viewed by browsers running on the local server machine.

Source File: D:\home\site\wwwroot\web.config Line: 8

Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.6.1590.0

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

错误页面的 HTML 源代码中有堆栈跟踪:

[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 应用服务的应用程序设置中的连接字符串部分删除连接字符串,应用程序将正常启动。如果我恢复它,该应用程序将再次在启动时失败。 这很奇怪!考虑一下!有连接字符串 - 失败,没有连接字符串 - 正常。
  • 当我在本地运行应用程序并且没有 Web.Secrets.ConnectionStrings.config 文件时,应用程序运行得很好。仅当部署在 Azure 应用服务中时,应用程序才会失败。 因此,该问题是 Azure 应用服务特有的。
  • 即使使用普通的空 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>

最佳答案

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

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

它也会以同样的方式爆炸(无法打开配置源文件“Web.Secrets.ConnectionStrings.config”。)。

这很有趣,因为通过应用设置,当文件丢失时,它可以简单地忽略 file 指令。

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

您需要取消该属性(如您所示),或部署一个虚拟文件以使其保持正常状态。

关于asp.net - 使用连接字符串 configSource 属性以及 Azure 应用服务环境连接字符串时,部署后启动失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40767601/

相关文章:

c# - FIPS 验证算法将密码存储在数据库中?

azure - 有没有办法在部署到azure(CD)过程中从CI Build的arm模板文件中提取功能应用程序名称

Azure DevOps REST API : Is there a way to show all fields of a workitem by running a WIQL through REST API

asp.net - 更新 Web 代码会导致 Designer.cs 文件将 WebControls.ListItem 替换为 HtmlControls.HtmlGenericControl

asp.net - <q> 元素未在 IE 6.0 中识别

asp.net - 对 ASP.NET 站点的更改是否会终止事件 session ?

c# - 从更长的字符串中提取字符串

c# - Autofac,如何使用方面的实例而不是方面的类型来拦截服务?

.net - 在两个 Visual Studio 实例(一个提升/管理员,一个普通)中使用签名依赖项

c# - 将 VS 2013 Community 升级到 Professional 后,无法在解决方案中加载 Azure 2.7 项目