Fix 550 5.7.1 Unable to relay

一个奇怪的问题,公司局域网内使用System.Web.Mail发信可以,但是不能发网外。异常为“The server rejected one or more recipient addresses. The server response was: 550 5.7.1 Unable to relay”。环境为Windows7+IIS7+VS2010。

了解到Windows Vista开始IIS7不再附带SMTP Service,如果是Windows XP+IIS6,修正方法如下:

System.Web.Mail is working correctly, and is attempting to send the email. However, your SmtpMail.SmtpServer is not allowing relaying. Try one of the following suggestions:

  • Make sure the MailMessage.From is a valid email address that exists on the SmtpMail.SmtpServer.
  • Allow relaying for your MailMessage.From address (see your specific mail server documentation for this)
  • Allow relaying for your IP Address (see your specific mail server documentation for this).
  • Try authenticated first, before sending the email. Check out 3.8 How do I authenticate to send an email?
  • If you are using the IIS SMTP Service try allowing relaying for your IP address by:
    • Opening the IIS Admin MMC
    • Right-Clicking on the SMTP Virtual Server and selecting Properties
    • On the Access tab, click the Relay button
    • Grant 127.0.0.1 (or the IP address used by System.Web.Mail) to the Computers list.
    • Close all dialogs
    • Restarting the SMTP Service

How do I authenticate to send an email?

If you are using the .NET Framework 1.0, this cannot be done. However, in the 1.1 version, the MailMessage.Fields property was added. This allowed access to the underlying CDO.Message fields.

The following example demonstrates sending your username and password to the SMTP server to provide authentication.

[ C# ]

private void Page_Load(object sender, System.EventArgs e)
{
	MailMessage mail = new MailMessage();
	mail.To = "me@mycompany.com";
	mail.From = "you@yourcompany.com";
	mail.Subject = "this is a test email.";
	mail.Body = "Some text goes here";
	mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1");	//basic authentication
	mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "my_username_here"); //set your username here
	mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "super_secret");	//set your password here

	SmtpMail.SmtpServer = "mail.mycompany.com";  //your real server goes here
	SmtpMail.Send( mail );
}

[ VB.NET ]

Private Sub Page_Load(sender As Object, e As System.EventArgs)
   Dim mail As New MailMessage()
   mail.To = "me@mycompany.com"
   mail.From = "you@yourcompany.com"
   mail.Subject = "this is a test email."
   mail.Body = "Some text goes here"
   mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", "1") 'basic authentication
   mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "my_username_here") 'set your username here
   mail.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "super_secret") 'set your password here
   SmtpMail.SmtpServer = "mail.mycompany.com" 'your real server goes here
   SmtpMail.Send(mail)
End Sub 'Page_Load

Windows7+IIS7的修正方法如下:

安装另一个SMTP服务器如,FreeSMTP。然后将SmtpMail.SmtpServer设为"localhost"。

参考文章:http://www.systemwebmail.com/faq/4.3.11.aspx

Advertisements

Asp.Net membership加密算法

算法思路:
明文=Salt(Salt为Base64编码,由GenerateSalt()产生)+Unicode编码的密码明文
密文=对明文进行sha1加密,再转Base64编码


internal string EncodePassword(string pass, int passwordFormat, string salt)
{ // passwordFormat is defined in webconfig
    if (passwordFormat == 0) // MembershipPasswordFormat.Clear
        return pass;

    byte[] bIn = Encoding.Unicode.GetBytes(pass);
    byte[] bSalt = Convert.FromBase64String(salt);
    byte[] bAll = new byte[bSalt.Length + bIn.Length];
    byte[] bRet = null;

    Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
    Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
    if (passwordFormat == 1)
    { // MembershipPasswordFormat.Hashed
        HashAlgorithm s = HashAlgorithm.Create(Membership.HashAlgorithmType); //HashAlgorithm.Create("sha1");
        bRet = s.ComputeHash(bAll);
    }
    else
    {
        bRet = EncryptPassword(bAll);
    }

    return Convert.ToBase64String(bRet);
}

public static string GenerateSalt()
{
    byte[] buf = new byte[16];
    (new RNGCryptoServiceProvider()).GetBytes(buf);
    return Convert.ToBase64String(buf);
}

参考文章:http://topic.csdn.net/u/20070904/10/64b82c12-ab52-487c-8285-29ad45408d71.html