【问题标题】:Unrecognized attribute 'configProtectionProvider' after encrypting app.config加密 app.config 后无法识别的属性“configProtectionProvider”
【发布时间】:2011-10-22 02:05:29
【问题描述】:

我在应用程序的开头运行以下方法,传入位于 applicationSettings 下的部分:

public static void EncryptConfigSection(string sectionKey)
    {
        Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        ConfigurationSection section = config.GetSection(sectionKey);
        if (section != null)
        {
            if (!section.SectionInformation.IsProtected)
            {
                if (!section.ElementInformation.IsLocked)
                {
                    section.SectionInformation.ProtectSection("RSAProtectedConfigurationProvider");
                    section.SectionInformation.ForceSave = true;
                    config.Save(ConfigurationSaveMode.Full);
                    ConfigurationManager.RefreshSection(sectionKey);
                }
            }
        }
    }

这是 app.config 中的部分示例:

<applicationSettings>
  <Example.Properties.Settings>
    <setting name="Key" serializeAs="String">
      <value>Value</value>
    </setting>
  </Example.Properties.Settings>
</applicationSettings>

当我尝试访问该部分的任何设置时,我收到以下错误:

无法识别的属性“configProtectionProvider”

这是一个桌面应用程序,需要在启动时加密一些设置,然后在退出时解密。

有人有解决这个问题的办法吗?

【问题讨论】:

    标签: c# asp.net winforms


    【解决方案1】:

    我发现了这个:http://andybrennan.wordpress.com/2014/06/05/unrecognized-attribute-configprotectionprovider-after-encrypting-app-config/。它解决了问题。

    只要使用博客上写的这个方法:

    private void ResetConfigMechanism()
    {
        typeof(ConfigurationManager)
            .GetField("s_initState", BindingFlags.NonPublic |
                                     BindingFlags.Static)
            .SetValue(null, 0);
    
        typeof(ConfigurationManager)
            .GetField("s_configSystem", BindingFlags.NonPublic |
                                        BindingFlags.Static)
            .SetValue(null, null);
    
        typeof(ConfigurationManager)
            .Assembly.GetTypes()
            .Where(x => x.FullName ==
                        "System.Configuration.ClientConfigPaths")
            .First()
            .GetField("s_current", BindingFlags.NonPublic |
                                   BindingFlags.Static)
            .SetValue(null, null);
    }
    

    保存/刷新配置后调用它。

    【讨论】:

    • 不是通过反射调用私有属性和方法的忠实粉丝,但是这个解决方案效果很好,并且是唯一解决我的问题的解决方案(复杂的配置模式包含文件和 settings.settings 文件在一些项目)。出于这个原因,给了它一个赞成票。我确保在我的代码中记录了使用情况,并指出每次我们更改 .NET Framework 的版本时都应该重新测试它,以确保它仍然有效,并检查微软是否实施了一种公共方式来做同样的事情。
    • 我试图从其他答案中得到一些工作,但这是唯一能始终如一的工作。
    • 如果允许的话,我会给 10 颗星。这段代码 sn-p 拯救了我的一天
    • 节省了我的一天,谢谢,快速肮脏的修复我讨厌它,但它有效。
    【解决方案2】:

    我设法让 Rick Schott 的答案起作用,但有一个重要警告 - 您不能使用 ConfigurationManager.GetSection 的静态版本在刷新后检索该部分 - 您必须改用 Configuration.GetSection

    完整代码:

    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
    ConfigurationSection section = config.GetSection("passwordSection") as ConfigurationSection;
    
    if (!section.SectionInformation.IsProtected)
    {
        // Encrypt the section.
        section.SectionInformation.ProtectSection("DPAPIProtection");
        section.SectionInformation.ForceSave = true;
        config.Save(ConfigurationSaveMode.Modified);
    
        // The passwords are now encrypted.
        // Refresh the *parent* of the section that your passwords are in.
        ConfigurationManager.RefreshSection("configuration");
    
        // Now use Configuration.GetManager to retrieve the new password section.
        // This doesn't throw the Configuration Exception :)
        ConfigurationSection section2 = config.GetSection("passwordSection") as ConfigurationSection;
    }
    

    【讨论】:

      【解决方案3】:

      根据这篇博文,解决方法是在父级上调用RefreshSection()

      RefreshSection("applicationSettings")
      

      Unrecognized attribute configProtectionProvider

      【讨论】:

      • 瑞克,很遗憾这不起作用。不知道为什么。我尝试了几种不同的方法。唯一有效的是,如果我加密配置然后启动应用程序。
      • @GrandMasterT 2 年太晚了,但我设法让 Rick 的答案起作用 - 请参阅我的答案了解详细信息 :) 另外,Rick +1 指导我到正确的地方!
      【解决方案4】:

      我无法在应用程序运行时加密/解密配置文件并继续读取值。

      虽然不是我想要的,但问题的解决方案是在应用程序运行之前首先加密/解密 .config。

      这是另一种我没有做过但看起来很有趣的方法: Encrypting Passwords in a .NET app.config File

      【讨论】:

        【解决方案5】:

        这篇文章拯救了我的一天,以防万一有人需要在 vb 和 2017 中进行修复

            Private Sub ResetConfigMechanism()
                GetType(ConfigurationManager).GetField("s_initState", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, 0)
                GetType(ConfigurationManager).GetField("s_configSystem", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, Nothing)
                GetType(ConfigurationManager).Assembly.GetTypes().Where(Function(x) x.FullName = "System.Configuration.ClientConfigPaths").First().GetField("s_current", BindingFlags.NonPublic Or BindingFlags.Static).SetValue(Nothing, Nothing)
            End Sub
        

        【讨论】:

          猜你喜欢
          • 2012-12-02
          • 2019-06-07
          • 2012-08-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多