2010-01-18 66 views
0

我有一个静态辅助方法,可以绕过SMTPClient发送电子邮件。凭证缓存问题

我将SMTP认证存储在web.config - > System.Net命名空间对象查找的默认位置。

我将凭据传递给SMTPClient,因为我想在SMTPClient使用此密码之前在密码上运行我的密码解密。

我在这里遇到的问题是 - 当我运行一次这个密码时,密码在缓存中以某种方式被“解密”。当我在同一个会话中第二次尝试运行此方法时,出现错误,因为它试图解密第一次运行时已解密的密码。有任何想法吗?

public static void SendEmail(MailMessage mailMessage) 
    { 
     SmtpClient smtpClient = new SmtpClient(); 
     NetworkCredential nc = new NetworkCredential(); 
     nc = (NetworkCredential)smtpClient.Credentials; 
     nc.Password = Tools.Decrypt(nc.Password); 
     smtpClient.Credentials = nc; 
     smtpClient.Send(mailMessage); 
     nc = null; 
     smtpClient.Credentials = null; 
    } 

回答

1

由于NetworkCredentials是您传递到您的NC变量的引用的类,这意味着当你解密你解密它的原始对象上的密码。

您可能需要克隆该对象,或者只在应用程序启动时执行一次该操作。

+0

谢谢。如果我在静态中使用它,为什么它会留在内存中? – user53885 2010-01-18 14:56:29

+0

有没有可能向我展示如何在Global.asax中执行此操作的简短示例?虽然仍然能够从静态使用它? – user53885 2010-01-18 15:12:44

+0

在SmtpClient对象的内部,通过静态属性设置凭证。因此,尽管您的SmtpClient已实例化,但每个请求凭证都使用相同的静态对象进行填充。 这意味着所有SmtpClient实例实际上都使用NetworkCredentials的相同静态实例。该属性在应用程序的整个生命周期中保持相同的对象引用。 – Mark 2010-01-18 15:23:32

0

一点点哈克,但只是把

SmtpClient smtpClient = new SmtpClient(); 
NetworkCredential nc = new NetworkCredential(); 
nc = (NetworkCredential)smtpClient.Credentials; 
nc.Password = Tools.Decrypt(nc.Password); 
smtpClient.Credentials = nc; 
smtpClient = null; 

在您的Global.asax可能做到这一点。然后有你的静态方法

SmtpClient smtpClient = new SmtpClient(); 
smtpClient.Send(mailMessage); 
smtpClient = null; 

,但我确定必须有一个更优雅的解决方案。

更新:你也许可以尝试使用SmtpNetworkElement并在global.asax上更新密码 - 我想只要你在使用SmtpClient之前这样做,它可能会工作。