含&字符的密码导致ASP.NET MVC3站点崩溃的原因排查
我有一个运行在IIS 7.5上的ASP.NET MVC3 C# .NET应用程序。我们在代码中模拟Windows NT服务账户,以实现对文件共享的读写操作,用户ID已编译到代码中,服务账户密码存储在web.config文件内。该密码包含&字符(示例:p&ssword),导致站点崩溃,访问时会收到“Sorry, an error occurred while processing your request”错误。以下是使用该密码的代码:
var password = ConfigurationManager.AppSettings.Get(Common.SVC_PWD); bool isSuccess = LogonUser( @"my_svc_acct", "my.domain.net", password, LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref token );
问题原因
web.config本质是XML格式文件,而&是XML中的预定义特殊字符(用于标记实体引用的开始,比如&代表&)。如果直接在web.config的<appSettings>里写入含&的密码,XML解析器会将其视为实体引用的起始符号,但后续没有匹配的合法实体名称(比如&ssword不是标准XML实体),导致XML解析失败,进而整个应用程序在读取配置时抛出未处理异常,最终表现为站点崩溃。
重启计算机无法解决问题,因为根源是配置文件的XML语法错误,和服务/系统运行状态无关。
解决办法
1. 转义XML特殊字符
把密码中的&替换为XML实体&,原密码p&ssword在web.config中需写成:
<add key="SVC_PWD" value="p&ssword" />
ConfigurationManager读取时会自动将&还原为&,不影响后续LogonUser的调用。
2. 使用CDATA包裹密码
如果密码包含多个XML特殊字符(如<、>、"、'、&),可以用CDATA段包裹,避免逐个转义:
<add key="SVC_PWD"> <![CDATA[p&ssword]]> </add>
3. 加密web.config中的敏感配置
从安全角度考虑,明文存储服务账户密码存在泄露风险,建议使用ASP.NET的配置加密功能(如RsaProtectedConfigurationProvider)对<appSettings>或单独的敏感节点进行加密,既解决特殊字符问题,又提升配置安全性。
内容的提问来源于stack exchange,提问作者Mochatitan

