【问题标题】:c# emailing using static method in separate classc# 在单独的类中使用静态方法发送电子邮件
【发布时间】:2014-04-15 14:08:44
【问题描述】:

我有一个小程序,它检查几个文件夹中的旧文件,如果找到它们,它会向我发送一封电子邮件。一切正常,但我的电子邮件用户名和密码硬编码为:

SmtpServer.Credentials = new System.Net.NetworkCredential(
    "uname@domain.com", "password");

一位朋友看过它并提到他将使用一个单独的类来使用静态方法重用电子邮件代码,但我不确定这是否会有所帮助(或如何实现)。我将开始使用 Git/GitHub 进行更改跟踪,我不想将我的电子邮件硬编码到公共存储库中。

我知道 smtp 密码需要在某个地方以纯文本形式出现,但我可以将其隐藏在我的代码之外并使用“使用”或其他选项调用它,这样密码就不会存储在代码中吗?

使用 Visual Studio Express 2012 编写的程序

编辑 1:应该说这只是一个控制台应用程序 .exe 文件,由 Windows 计划任务调用以在远程服务器上执行某些文件夹监视。所以它是在我的电脑上编译的,但是 exe 文件被保存并计划远程运行。

【问题讨论】:

  • 也许如果您在 xml 或其他文件中拥有电子邮件和密码,并且您从中检索了这些信息?您不需要在 github 中拥有它。从文件中获取信息是 c# 中的简单代码

标签: c# git


【解决方案1】:

我可以将它隐藏在我的代码之外并使用“使用”或其他选项调用它,这样密码就不会存储在代码中吗?

当然,将信息存储在某个配置文件中。以编程方式读入文件。当然,这里的问题是,在许多情况下,单独的配置文件比在编译代码中暴露更多

您可以加密信息,然后只将加密版本存储在配置文件中,但是无论是您的配置文件还是程序中的其他位置,您都需要存储私钥来解密密码。您现在基本上已经提出了这个问题,因为您现在需要知道在哪里安全地存储私钥。这使得这个问题实际上无法解决。您可以通过将某些信息深埋或要求某人跳过很多圈才能找到它,从而使某些信息更难找到,但是如果程序有某种方法可以获取某些敏感信息,并且您具有智能,有决心的、恶意的人可以访问该程序,那么他们最终将能够访问它。

【讨论】:

    【解决方案2】:

    我确信有很多解决方案,但您可以做的一件事是将您的电子邮件凭据存储在您的 app.config 中,然后像这样访问它们:

    string email = ConfigurationManager.AppSettings["Email"];
    string password = ConfigurationManager.AppSettings["Password"];
    

    【讨论】:

    • 当然,现在任何在给定程序时打开配置文件的人现在都有他的电子邮件/密码。这在很多方面实际上是更糟糕的
    • 您只需更改公共存储库的这些值。仅将真实凭据投入生产。
    • 假设这是在一些受控服务器上运行的代码,而不是桌面应用程序。
    【解决方案3】:

    对于诸如凭据(用户名和密码)之类的东西,通常最好将它们视为环境配置详细信息。也就是说,对于在任何给定环境中运行的应用程序的任何给定实例,它都需要一些可配置的值来与邮件服务器交互:

    • 主机名
    • 用户名
    • 密码

    环境配置通常放在App.configWeb.config 文件中。在最简单的情况下,您可能在配置文件中有这样的内容:

    <appSettings>
      <add key="SMTPUsername" value="uname@domain.com" />
      <add key="SMTPPassword" value="password" />
    </appSettings>
    

    然后要将它们从代码中的配置中提取出来,您需要执行以下操作:

    SmtpServer.Credentials = new System.Net.NetworkCredential(
        System.Configuration.ConfigurationManager.AppSettings["SMTPUsername"],
        System.Configuration.ConfigurationManager.AppSettings["SMTPPassword"]);
    

    您可以在自定义配置类后面抽象这些设置,在配置中为空值的情况下使用代码内默认值,对配置值进行各种错误检查等。但最终您要从中提取值配置文件。

    然后可以将配置文件与公开可见的源代码分开。您希望源代码中包含一个配置文件,其中包含示例配置数据,因此使用该项目的人现在可以如何配置它。但是您可以根据自己的需要保留未签入的本地配置,并将自定义配置文件部署到运行此应用程序的任何生产服务器。 (这就是配置文件的真正用途,存储同一应用程序实例之间不同的值。)

    您是否创建static 辅助方法来处理此问题与隐藏这些值并不真正相关。你当然可以创建这样的方法。如果您更喜欢要实例化的邮件程序对象,它不需要是静态的。 (也许是实现了IDisposable 并使用它在内部处理 SMTP 对象资源的东西?发挥你想要的创造力,真的。)但这种抽象本身并不能隐藏你的值,它只是将它们从源中的一个类中移出代码到另一个。您想将它们从源代码中完全删除。

    【讨论】:

    • 你说得比我更有说服力。很好的答案。
    • 我添加了这个,看起来这正是我想要做的。我将一个示例配置文件上传到存储库(以百万分之一的机会查看我糟糕的项目),而具有所有实际信息的本地配置文件仅驻留在本地。此外,为了让 System.Configuration.ConfigurationManager.AppSettings 显示为可用的程序集引用,您需要添加它。查看所有投票中关于 5 个答案的评论。 stackoverflow.com/questions/1274852/…
    【解决方案4】:

    您是否尝试将这些值添加到您的应用程序设置中?

    您可以从项目菜单访问设置,查找“属性...”。这将打开属性页面,在左侧您将看到“设置”。填写您的设置名称(例如“密码”)并输入(可能是字符串)。该值将保存在项目中名为“app.config”的 xml 文件中。编译后,您会看到该文件为“.exe.config”。您可以在部署后修改该配置文件。

    在代码中按名称访问该值:

    SmtpServer.Credentials = new System.Net.NetworkCredential(
        "uname@domain.com", Properties.Settings.Default.Password);
    

    这样您就可以修改设置,而无需将机密信息提交到某个存储库。

    【讨论】:

      【解决方案5】:

      将其移动到另一个 DLL 将无助于隐藏此信息,为此,保护它的一种非常简单(但基本)的方法是首先将其移动到您的用户信息到您的应用配置中,例如

      <appSettings>
        <add key="user" value="user@mydomain.com" />
        <add key="pwd" value="some password" />
      </appSettings>
      

      接下来您需要对该部分进行加密,如果它是一个网络应用程序,您只需运行以下代码,它就会为您完成工作

      aspnet_regiis -pe "WebConfigSectionName" -app "/WebAppName"
      

      如果您的应用不是网络应用,那么您仍然可以对其进行加密,但您需要编写自己的加密例程,请参阅MSDN article

      最后,在您的代码中,您应该能够从配置中读取数据,请注意,距离我上次这样做已经有一段时间了,所以请尝试一下,但我认为您不需要任何特别的东西来阅读它在

      string user = ConfigurationManager.AppSettings["user"];
      string pwd = ConfigurationManager.AppSettings["pwd"];
      

      警告:如果我没记错的话,您运行加密的用户上下文和您的应用程序必须相同或可以访问相同的密钥,这意味着,如果您运行应用程序(或aspnet_regiis) 将应用程序配置部分加密为“MySecurityUser”,则在需要读取加密部分时运行应用程序的帐户必须是“MySecurityUser”,不能是“DaveUserId”(您将无法解密)它)

      【讨论】:

        【解决方案6】:

        是否可以要求他们输入自己的电子邮件信息?

        一种选择是将其放入注册表中:

        http://www.codeproject.com/Articles/3389/Read-write-and-delete-from-registry-with-C

        另一种选择是使用 web.debug.config 并且不包含在存储库中:

        How can I use Web.debug.config in the built-in visual studio debugger server?

        【讨论】:

          【解决方案7】:

          如果您将在同一台 PC 上运行应用程序,则可以使用 ProtectedData。

          所以首先加密您的用户名和密码(即在调试模式下,保存它,然后在 .cs 文件中使用加密字符串)。

          SmtpServer.Credentials = 新 System.Net.NetworkCredential( ProtectedData.Unprotect([encrypted]), ProtectedData.Unprotect([这里是加密数据]));

          【讨论】:

            猜你喜欢
            • 2017-04-30
            • 2016-04-17
            • 1970-01-01
            • 2010-11-21
            • 2017-12-07
            • 1970-01-01
            • 1970-01-01
            • 2016-03-29
            • 2012-02-25
            相关资源
            最近更新 更多