【问题标题】:Encrypting XML custom configuration file加密 XML 自定义配置文件
【发布时间】:2015-08-11 22:32:02
【问题描述】:

我有这个方法可以从我的 XML“自定义配置”配置文件中填充一个对象:

public static BindingList<StationConfiguration> GetStationsFromConfigFile()
{
    string xmlDocumentText = File.ReadAllText(GetConfigFilePath());
    var doc = new XmlDocument();
    doc.LoadXml(xmlDocumentText);

    BindingList<StationConfiguration> stations = new BindingList<StationConfiguration>();
    foreach (XmlNode node in doc.DocumentElement["StationsSection"].ChildNodes[0].ChildNodes)
    {
        stations.Add(
            new StationConfiguration(
                node.Attributes["Comment"].Value
                , node.Attributes["FtpUsername"].Value
                , node.Attributes["FtpPassword"].Value
                , node.Attributes["DestinationFolderPath"].Value
            ));
    }

    return stations;
}

如您所见,我使用File.ReadAllText 将 XML 配置文件的内容拉入字符串。

这一切都适用于非加密配置文件。但现在我需要加密它。 MSDN suggests 这样做的方式是这样开始的:

System.Configuration.Configuration config =
    ConfigurationManager.OpenExeConfiguration(
    ConfigurationUserLevel.None);

(顺便说一下,当我查看config.FilePath 属性时,它向我显示了XML 配置文件的正确路径,只是出于某种奇怪的原因有一个额外的“.config”扩展名。它以“.exe.config”结尾.config" 出于某种奇怪的原因。但我离题了...)

这是我的StationConfigurationSection 班级:

public class StationConfigurationSection : ConfigurationSection
{
    [ConfigurationProperty("Stations", IsDefaultCollection = false)]
    [ConfigurationCollection(typeof(StationCollection),
        AddItemName = "add",
        ClearItemsName = "clear",
        RemoveItemName = "remove")]
    public StationCollection Stations
    {
        get
        {
            return (StationCollection)base["Stations"];
        }
    }

    public override bool IsReadOnly()
    {
        return false;
    }
}

我的完整 XML 配置文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="StationsSection" type="EcFtpClient.StationConfigurationSection, EcFtpClient" />
  </configSections>
  <StationsSection>
    <Stations>
      <add Comment="ABC" FtpUsername="eliezer" FtpPassword="secret" DestinationFolderPath="C:\Users\eliezer\Desktop\local dest" FtpTimeoutInSeconds="30" FtpHostname="ftp://192.168.1.100/" FtpFolderPath="" />
    </Stations>
  </StationsSection>
  <startup>
    <supportedRuntime version="v2.0.50727" />
  </startup>
  <appSettings>
    <add key="NameOfService" value="ECClient" />
    <add key="PollingFrequencyInSeconds" value="60" />
  </appSettings>
</configuration>

我想使用 MSDN System.Configuration 方法,因为它使加密/解密非常容易,但我怎样才能将他们的方法与我必须使它工作的方法结合起来呢?


-- 更新 --
我已加载文件,但在保存文件时仍然卡住。

我已更改加载方法(在这个问题的最上面)到这个:

public static BindingList<StationConfiguration> GetStationsFromConfigFile()
{
    Configuration config = ConfigurationManager.OpenExeConfiguration(GetConfigFilePath());
    StationConfigurationSection stationsConfig = (StationConfigurationSection)config.GetSection("StationsSection");
    var stationCollection = ((StationCollection)stationsConfig.Stations);

    BindingList<StationConfiguration> stationsToReturn = new BindingList<StationConfiguration>();

    for (int index = 0; index < stationCollection.Count; index++)
    {
        stationsToReturn.Add(
            new StationConfiguration(
                stationCollection[index].Comment,
                stationCollection[index].FtpUsername,
                stationCollection[index].FtpPassword,
                stationCollection[index].DestinationFolderPath)
            );

    return stationsToReturn;
}

让我感到高兴的是,无论文件是否加密,它都能加载文件——它加载成功。太好了。

但我仍然不确定如何进行保存。这是我的保存方法:

public static void SaveStationsToConfigFile(BindingList<StationConfiguration> updatedStations, bool isConfigToBeEncrypted)
{
    string configFilePath = GetConfigFilePath();

    var xDoc = XDocument.Load(configFilePath);
    var xDeclaration = xDoc.Declaration;
    var xElement = xDoc.XPathSelectElement("//StationsSection/Stations");

    // clear out existing station configurations
    xDoc.Descendants("Stations").Nodes().Remove();

    foreach (var station in updatedStations)
    {
        xElement.Add(new XElement("add",
                new XAttribute("Comment", station.Station),
                new XAttribute("FtpUsername", station.Username),
                new XAttribute("FtpPassword", station.Password),
                new XAttribute("DestinationFolderPath", station.FolderName),
                new XAttribute("FtpTimeoutInSeconds", 30),
                new XAttribute("FtpHostname", GetEnvironmentAppropriateFtpHostName()),
                new XAttribute("FtpFolderPath", GetEnvironmentAppropriateFtpFolderPath())
        ));
    }

    xDoc.Declaration = xDeclaration;
    xDoc.Save(configFilePath);
}

为了使用保护/加密保存它,我需要做这样的事情 - 换句话说,使用 System.Configuration.Configuration 对象:

stationsConfig.SectionInformation.ProtectSection("RsaProtectedConfigurationProvider");
stationsConfig.SectionInformation.ForceSave = true;
objConfig.Save(ConfigurationSaveMode.Modified);

但我目前仍在使用XDocument.Save 进行保存...

有没有办法将我的 XDocument 转换为 System.Configuration.Configuration 兼容对象?
想到的 hack 是在调用 XDocument.Save 之后 -加载它并使用System.Configuration.Configuration 东西再次保存它。但这是一个黑客......

【问题讨论】:

    标签: c# xml winforms encryption configuration-files


    【解决方案1】:

    我相信你必须和configuration settings framework一起玩。与其尝试自己打开 xml 文件,不如创建 ConfigurationSection 的后代。

    这样它将为您从加密配置中读取和写入。

    您似乎已经开始了该路线 (EcFtpClient.StationConfigurationSection),但您没有包含任何该代码。

    【讨论】:

    猜你喜欢
    • 2011-01-10
    • 1970-01-01
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2014-05-03
    • 1970-01-01
    相关资源
    最近更新 更多