c#在单独的类中使用静态方法发送邮件

本文关键字:静态方法 单独 | 更新日期: 2023-09-27 17:49:38

我有一个小程序,它会检查几个文件夹中是否有旧文件,如果找到了,它会给我发一封电子邮件。一切工作,但我有我的电子邮件用户名和密码硬编码为:

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

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

我知道smtp密码需要在纯文本的某个地方工作,但我可以隐藏在我的代码之外,并调用它与一个"使用"或其他选项,所以密码不存储在代码?

使用Visual Studio Express 2012编写程序

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

c#在单独的类中使用静态方法发送邮件

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

  • 用户名

环境配置一般放在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 helper方法来处理这个与隐藏这些值无关。您当然可以创建这样的方法。它不需要是静态的,如果您喜欢实例化的邮件器对象。(也许是实现IDisposable的东西,并使用它来内部处理SMTP对象资源?发挥你的创造力吧,真的。)但是这种抽象本身并不能隐藏您的值,它只是将它们从源代码中的一个类移动到另一个类。您希望完全从源代码中删除它们。

将其移动到另一个DLL中不会帮助隐藏此信息,要做到这一点,一个非常简单(但基本)的保护方法是首先将其移动到您的用户信息到您的应用程序配置中,如

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

接下来你需要加密该部分,如果它是一个web应用程序,你可以运行下面的代码,它会为你做的

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

如果你的应用程序不是web应用程序,那么你仍然可以加密它,但你需要编写自己的加密例程,请参阅MSDN文章

最后,在你的代码中,你应该能够从配置中读取数据,请注意,自从我上次这样做已经有一段时间了,所以尝试一下,但我认为你不需要任何特殊的东西来读取 中的数据
string user = ConfigurationManager.AppSettings["user"];
string pwd = ConfigurationManager.AppSettings["pwd"];

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

我可以把它隐藏在我的代码之外,并使用'using'或其他选项调用它,以便密码不存储在代码中吗?

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

您可以加密信息,然后只将加密的版本存储在配置文件中,但是然后无论是您的配置文件,还是您的程序中的其他地方,您都需要存储私钥来解密密码。您现在基本上已经提出了这个问题,因为您现在需要知道在哪里安全地存储私钥。这使得这个问题实际上无法解决。你可以把一些信息埋藏得很深,或者要求某些人绕过重重障碍才能找到,但如果程序有办法获取一些敏感信息,而且你有一个聪明的、坚定的、恶意的人可以访问该程序,那么他们最终将能够获得这些信息。

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

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

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

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

在代码中通过名称访问该值:

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

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

让他们输入自己的电子邮件信息是可能的吗?

一个选项是把它放在注册表中:

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

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

如何在内置的visual studio调试器服务器中使用Web.debug.config ?

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

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

SmtpServer。新建System.Net.NetworkCredential(ProtectedData ProtectedData.Unprotect((加密))。Unprotect([此处加密的数据]));