2010-03-11 823 views
6

Necesito validar el nombre de usuario y la contraseña establecidos en una instancia de SmtpClient antes de enviar el correo. Utilizando este código:¿Cómo validar las credenciales smtp antes de enviar el correo?

SmtpClient client = new SmtpClient(host); 
client.Credentials = new NetworkCredential(username,password); 
client.UseDefaultCredentials = false; 

// Here I need to verify the credentials(i.e. username and password) 
client.Send(mail); 

¿Cómo puedo validar si se permite que el usuario identificado por las credenciales para conectarse y enviar un correo electrónico?

Respuesta

3

No hay manera.

SmtpClient básicamente no puede validar el usernamepassword sin ponerse en contacto con el servidor al que se conecta.

Lo que podría hacer es hacerlo fuera de SmtpClient, abriendo una conexión TCP al servidor ... pero la autenticación PUEDE ser complicada según cómo esté configurado el servidor.

¿Puedo preguntar POR QUÉ necesita saber eso antes de enviar? El comportamiento normal en mi humilde opinión sería envolver el envío en el manejo de errores adecuado para detectar excepciones aquí.

+0

lo que necesitaba saber si la validación se puede hacer. Como ocurre en MS Outlook, antes de enviar correos, solicita el nombre de usuario y la contraseña si están equivocados. Yo quería hacer lo mismo en mi aplicación. Agradezco su ayuda. –

+0

En realidad, obtienes algo mal aquí. MS Outlook NO te pregunta antes de enviar correos electrónicos.Te pregunta solo en 1 ogro: no puede autenticarse. Lo intenta si configura passord. Puede preguntar si lo configuró para hacerlo. Pero está perfectamente feliz de intentar sin contraseña en caso de duda. – TomTom

1

Validando antes, el envío de correo no es posible con la clase de cliente SMTP en .net 2.0.

Intentar validar a mano, al abrir un puerto es tan bueno como escribir su propio cliente SMTP, es complejo.

1

.net SmtpClient no permite iniciar sesión sin enviar un mensaje.

Puede verificar las credenciales enviando un mensaje de prueba a alguna dirección existente que ignore el correo electrónico entrante y verifique si obtiene una excepción.

Tenga en cuenta que estos mensajes de correo electrónico de prueba aparecerán en la carpeta de enviados de su cuenta, en su caso (por ejemplo, Gmail)

0

estoy de acuerdo con las respuestas anteriores, que SmtpClient no puede validar sin enviar.

Pero tal vez su problema se puede resolver de todos modos: si el nombre de usuario o la contraseña son incorrectos, client.Send(mail); lanzará una excepción. Puede construir un while-loop y un try-catch-block alrededor del envío, detectar la excepción y pedirle al usuario el nombre de usuario y contraseña correctos, luego intente de nuevo. Si el usuario hace clic en cancelar en el cuadro de diálogo o si se envía correctamente sin excepción, sale del ciclo while.

1

Prueba esto:

try 
{ 
    smtpClient.Send(new MailMessage("[email protected]", "[email protected]", "test", "test")); 
    return string.Empty; 
} 
catch (SmtpFailedRecipientException) 
{ 
    return string.Empty; 
} 
catch (Exception ex) 
{ 
    return string.Format("SMTP server connection test failed: {0}", ex.InnerException != null ? ex.InnerException.Message : ex.Message); 
} 

Funciona para mí en mi método de validación. Pero si solo necesita verificar las credenciales al enviar un correo electrónico, simplemente rodee su envío con try ... catch.

+0

Test.com es un dominio real. No revisé si tiene un registro MX, pero cualquiera que solo copie el fragmento de código podría hacer que el servidor de correo intente enviar correos electrónicos reales a test.com. Recomiendo que edite su ejemplo con un nombre de dominio que realmente no existe (y que probablemente nunca exista). – Christoph

2

Mi código de producción para el nombre de usuario y contraseña antes de la validación al enviar correo:

public static bool ValidateCredentials(string login, string password, string server, int port, bool enableSsl) { 
     SmtpConnectorBase connector; 
     if (enableSsl) { 
      connector = new SmtpConnectorWithSsl(server, port); 
     } else { 
      connector = new SmtpConnectorWithoutSsl(server, port); 
     } 

     if (!connector.CheckResponse(220)) { 
      return false; 
     } 

     connector.SendData($"HELO {Dns.GetHostName()}{SmtpConnectorBase.EOF}"); 
     if (!connector.CheckResponse(250)) { 
      return false; 
     } 

     connector.SendData($"AUTH LOGIN{SmtpConnectorBase.EOF}"); 
     if (!connector.CheckResponse(334)) { 
      return false; 
     } 

     connector.SendData(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{login}")) + SmtpConnectorBase.EOF); 
     if (!connector.CheckResponse(334)) { 
      return false; 
     } 

     connector.SendData(Convert.ToBase64String(Encoding.UTF8.GetBytes($"{password}")) + SmtpConnectorBase.EOF); 
     if (!connector.CheckResponse(235)) { 
      return false; 
     } 

     return true; 
    } 

Más detalles en la respuesta a una similar question.

Code on github

+0

Ahora estoy usando lib MimeKit. Trabaja con cualquier tipo de auth. Y funciona bien en mi producción. http://www.mimekit.net/ –

Cuestiones relacionadas