Отправка письма через SMTP c NTLM-аутентификацией

Однажды, придя к заказчику, я не смог подключиться к их заранее заведенному электронному адресу для рассылок. Назовем его noreply@sample.com. Пришлось демонстрировать систему с ящиком yandex.ru. Основное предположение было то, что дело в домене. Так и оказалось, для подключения к SMTP нужно было пройти NTLM-аутентификацию (Статья о NTLM в Википедии).
Сперва у меня не получалось, т.к. использовал старую библиотеку mail.jar (версия: 1.4, размер: 379 КБ), потом скачал новую версию библиотеки, которая поддерживает NTLM: javax.mail.jar (версия: 1.5, размер: 533 КБ).
Эту версию можно скачать отсюда: javax.mail.jar

В этот статье вы встретите две реализации: одна реализация с обычным подключением к SMTP, а другая реализация с NTLM-авторизацией.

Для начала рассмотрим обычное подключение, чтобы потом увидеть разницу.
Созданим класс MailHelper, в конструкторе этого класса будут задаваться все необходимые параметры для подключения к почтовому ящику, а метод send будет отвечать за отправку писем согласно переданным в этот метод параметрам:

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
 
public class MailHelper {
 
	private Properties properties;
	private Session session;
	private String currentEmail;
 
	public MailHelper(String host,String port,final String user,final String password){
		properties = new Properties();
		properties.setProperty("mail.smtp.auth","true");
		properties.setProperty("mail.smtp.host", host);
		properties.setProperty("mail.smtp.port",port);
		currentEmail = user;
		session = Session.getInstance(properties,
		  new javax.mail.Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(user,password);
      			}
      		  });
	}
 
	public void send(String email,String subject,String body) throws Exception{
		MimeMessage msg = new MimeMessage(session);
		msg.setFrom(new InternetAddress(currentEmail));
		msg.setRecipient(Message.RecipientType.TO, new InternetAddress(email));
		msg.setSubject(subject);
		msg.setContent(body, "text/html; charset=utf-8");
		Transport.send(msg);
	}
}

Пример использования этого класса:

MailHelper mailHelper = new MailHelper(
		"smtp.sample.com","25",
		"noreply@sample.com","password123");
try {
	mailHelper.send("target@sample.com", "Проверка", "Привет, <b>Target</b>!");
} catch (Exception e) {
	e.printStackTrace();
}

В конструктор передаются: адрес SMTP-сервера, порт, логин и пароль.
В метод send передаются: электронный адрес получателя, заголовок и содержимое письма.

Теперь рассмотрим реализацию с NTLM. Практически тоже самое, только при создании объекта класса PasswordAuthentication нужно указать имя учетной записи в домене, а адрес электронной почты передается отдельным параметром.

import javax.mail.*;
import javax.mail.internet.*;
import java.util.*;
 
public class MailHelper {
 
	private Properties properties;
	private Session session;
	private String currentEmail;
 
	public MailHelper(String host,String port,
		final String user,final String password,String email){
		properties = new Properties();
		properties.setProperty("mail.smtp.auth","true");
		properties.setProperty("mail.smtp.host", host);
		properties.setProperty("mail.smtp.port",port);
		currentEmail = email;
		session = Session.getInstance(properties,
      		  new javax.mail.Authenticator() {
      			protected PasswordAuthentication getPasswordAuthentication() {
      				return new PasswordAuthentication(user,password);
      			}
      		  });
	}
 
	public void send(String email,String subject,String body) throws Exception{
		MimeMessage msg = new MimeMessage(session);
		msg.setFrom(new InternetAddress(currentEmail));
		msg.setRecipient(Message.RecipientType.TO, new InternetAddress(email));
		msg.setSubject(subject);
		msg.setContent(body, "text/html; charset=utf-8");
		Transport.send(msg);
	}
}

Пример использования:

MailHelper mailHelper = new MailHelper("192.168.0.2","25",
	"noreply","password123","noreply@sample.com");
try {
	mailHelper.send("target@sample.com", "Проверка", "Привет, <b>Target</b>!");
} catch (Exception e) {
	e.printStackTrace();
}

Конструктор принимает следующий параметры:
Адрес и порт SMTP-сервера, доменную учетную запись и пароль, а также адрес электронной почты, от имени которой будут уходить письма.
Метод send принимает те же параметры, что и в предыдущем примере: адрес получателя, тема и содержимое письма.

В итоге на указанный ящик должно прийти сообщение:

Привет, Мир! 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.