web-dev-qa-db-fra.com

Comment envoyer un email en utilisant MS Exchange Server

J'essaie d'envoyer un courrier électronique à l'aide du serveur de messagerie de mon entreprise. Mais je reçois l'exception suivante

Caused by: com.Sun.mail.smtp.SMTPSendFailedException: 530 5.7.1 Client was not authenticated
    at com.Sun.mail.smtp.SMTPTransport.issueSendCommand(SMTPTransport.Java:1388)
    at com.Sun.mail.smtp.SMTPTransport.mailFrom(SMTPTransport.Java:959)
    at com.Sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.Java:583)
    at javax.mail.Transport.send0(Transport.Java:169)
    at javax.mail.Transport.send(Transport.Java:98)

Voici mon exemple de code,

Properties props = System.getProperties();

// Setup mail server
props.put("mail.smtp.Host", "example.server.com");
props.put("mail.smtp.auth", "true");
props.put("mail.debug", "true");
props.put("mail.smtp.port", "25");
// Get session
//Session session = Session.getDefaultInstance(props, null);
Session session = Session.getDefaultInstance(props,
    new javax.mail.Authenticator() {
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("username", "password");
        }
    });

// Define message
MimeMessage message = new MimeMessage(session);

// Set the from address
message.setFrom(new InternetAddress(from));

// Set the to address
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

// Set the subject
message.setSubject("Hello JavaMail");

// Set the content
message.setText("Welcome to JavaMail");

// Send message
Transport.send(message);

Quel est le code erroné? En tant que nom d'utilisateur et mot de passe, j'utilise l'adresse e-mail et le mot de passe de mon entreprise.

11
user509755

Le 5.7.1 est probablement causé par un échange et non par votre code. Vous devrez peut-être simplement activer le relais sur le serveur. Soit pour les utilisateurs anonymes ou à partir d'une certaine adresse IP. Je ne suis pas un expert en échange, mais je travaille avant. Voici la dernière solution que j'ai testée qui fonctionne:

Si une erreur 5.7.1 est rencontrée lors de la tentative d'envoi d'un courrier électronique via SMTP sur un serveur d'échange lorsque l'utilisateur a été authentifié. 

Pour des raisons de référence, le problème que vous venez de rencontrer est dû à un paramètre défini sur le serveur Exchange 2007 - il ne s'agirait normalement pas d'un problème sur le serveur 2003 

Fixé en faisant ci-dessous ... 

Vous pouvez définir ce paramètre d'authentification via l'interface graphique

  • Dans Configuration du serveur/Transport Hub/Par défaut <Nom du serveur>
  • Clic droit, propriétés, groupes de permissions
  • Cochez "Utilisateurs anonymes" puis cliquez sur OK 

Évidemment, anon utilisateurs n’est pas trop sécurisé mais vous pouvez voir si cela résout le problème.

6
WraithNath

Mail.jar (version 1.4.0) a un problème de compatibilité avec MS Exchange Server et lève 530 5.7.1 Client was not authenticated, même lorsque le nom d'utilisateur et le mot de passe sont configurés.

La mise à niveau de l'API de messagerie à la version 1.4.4 OR 1.4.7 devrait résoudre le problème.

L'API de messagerie 1.4.7 peut être téléchargée à partir de l'adresse URL suivante: http://www.Oracle.com/technetwork/Java/javamail/index.html

2
Kamran

Dans certaines entreprises, la prise en charge du serveur Exchange SMTP est désactivée et vous ne pouvez pas leur demander de l'activer. Dans ces cas, une solution raisonnable est celle-ci:

http://davmail.sourceforge.net/

2
BrunoJCM

Je devais utiliser javamail + exchange. Les messages renvoyés étaient impuissants. Grâce à la pile, j'ai eu quelques indices.

Ajoutez ceci à votre code

  props.put("mail.smtp.starttls.enable","true");

Pensez également à ajouter les certificats des machines utilisées. Pour les trouver, il vous suffit d’accéder à votre navigateur, de les exporter et de les importer dans le fichier cacerts en cours d’utilisation.

1
Jerome_B

Simple Java Mail a travaillé pour moi. La seule chose que vous devez vérifier concerne le correct nomhôte , nomutilisateur , port et mot de passe TransportStrategy.SMTP_TLS:

new Mailer(Host, port, username, password, TransportStrategy.SMTP_TLS).sendMail(email);
1
zeddarn

Lorsque je vais utiliser un serveur MS Exhange SMTP pour envoyer un courrier électronique, j'utilise la dépendance maven ci-dessus.

<dependency>
    <groupId>com.Microsoft.ews-Java-api</groupId>
    <artifactId>ews-Java-api</artifactId>
    <version>2.0</version>
</dependency>

Pour cette raison, j'ai créé une classe qui représente un client de messagerie pour les serveurs MS Exchange. J'utilise log4j pour la journalisation.

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

Au-dessous de la classe client MS Exchange (j'utilise le modèle de générateur pour la construction de l'objet pour la sécurité des threads),

import Java.net.URI;
import Java.net.URISyntaxException;
import Java.util.ArrayList;
import Java.util.Arrays;
import Java.util.List;
import Microsoft.exchange.webservices.data.core.ExchangeService;
import Microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
import Microsoft.exchange.webservices.data.core.exception.service.local.ServiceLocalException;
import Microsoft.exchange.webservices.data.core.service.item.EmailMessage;
import Microsoft.exchange.webservices.data.credential.ExchangeCredentials;
import Microsoft.exchange.webservices.data.credential.WebCredentials;
import Microsoft.exchange.webservices.data.property.complex.MessageBody;
import org.Apache.log4j.Logger;

/**
 * A client to connect to a MS Exchange SMTP Server.
 */
public final class ExchangeClient {

    private static final Logger LOGGER = Logger.getLogger(ExchangeClient.class);

    private final String hostname;
    private final ExchangeVersion exchangeVersion;
    private final String domain;
    private final String username;
    private final String password;
    private final String subject;
    private final String recipientTo;
    private final List<String> recipientCc;
    private final List<String> recipientBcc;
    private final List<String> attachments;
    private final String message;

    private ExchangeClient(ExchangeClientBuilder builder) {
        this.hostname = builder.hostname;
        this.exchangeVersion = builder.exchangeVersion;
        this.domain = builder.domain;
        this.username = builder.username;
        this.password = builder.password;
        this.subject = builder.subject;
        this.recipientTo = builder.recipientTo;
        this.recipientCc = builder.recipientCc;
        this.recipientBcc = builder.recipientBcc;
        this.attachments = builder.attachments;
        this.message = builder.message;
    }

    public static class ExchangeClientBuilder {

        private String hostname;
        private ExchangeVersion exchangeVersion;
        private String domain;
        private String username;
        private String password;
        private String subject;
        private String recipientTo;
        private List<String> recipientCc;
        private List<String> recipientBcc;
        private List<String> attachments;
        private String message;

        public ExchangeClientBuilder() {
            this.exchangeVersion = ExchangeVersion.Exchange2010_SP1;
            this.hostname = "";
            this.username = "";
            this.password = "";
            this.subject = "";
            this.recipientTo = "";
            this.recipientCc = new ArrayList<>(0);
            this.recipientBcc = new ArrayList<>(0);
            this.attachments = new ArrayList<>(0);
            this.message = "";
        }

        /**
         * The hostname of the Exchange Web Service. It will be used for
         * connecting with URI https://hostname/ews/exchange.asmx
         *
         * @param hostname the hostname of the MS Exchange Smtp Server.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder hostname(String hostname) {
            this.hostname = hostname;
            return this;
        }

        /**
         * The Exchange Web Server version.
         *
         * @param exchangeVersion the Exchange Web Server version.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder exchangeVersion(ExchangeVersion exchangeVersion) {
            this.exchangeVersion = exchangeVersion;
            return this;
        }

        /**
         * The domain of the MS Exchange Smtp Server.
         *
         * @param domain the domain of the Active Directory. The first part of
         * the username. For example: MYDOMAIN\\username, set the MYDOMAIN.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder domain(String domain) {
            this.domain = domain;
            return this;
        }

        /**
         * The username of the MS Exchange Smtp Server. The second part of the
         * username. For example: MYDOMAIN\\username, set the username.
         *
         * @param username the username of the MS Exchange Smtp Server.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder username(String username) {
            this.username = username;
            return this;
        }

        /**
         * The password of the MS Exchange Smtp Server.
         *
         * @param password the password of the MS Exchange Smtp Server.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder password(String password) {
            this.password = password;
            return this;
        }

        /**
         * The subject for this send.
         *
         * @param subject the subject for this send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder subject(String subject) {
            this.subject = subject;
            return this;
        }

        /**
         * The recipient for this send.
         *
         * @param recipientTo the recipient for this send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder recipientTo(String recipientTo) {
            this.recipientTo = recipientTo;
            return this;
        }

        /**
         * You can specify one or more email address that will be used as cc
         * recipients.
         *
         * @param recipientCc the first cc email address.
         * @param recipientsCc the other cc email address for this send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder recipientCc(String recipientCc, String... recipientsCc) {
            // Prepare the list.
            List<String> recipients = new ArrayList<>(1 + recipientsCc.length);
            recipients.add(recipientCc);
            recipients.addAll(Arrays.asList(recipientsCc));
            // Set the list.
            this.recipientCc = recipients;
            return this;
        }

        /**
         * You can specify a list with email addresses that will be used as cc
         * for this email send.
         *
         * @param recipientCc the list with email addresses that will be used as
         * cc for this email send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder recipientCc(List<String> recipientCc) {
            this.recipientCc = recipientCc;
            return this;
        }

        /**
         * You can specify one or more email address that will be used as bcc
         * recipients.
         *
         * @param recipientBcc the first bcc email address.
         * @param recipientsBcc the other bcc email address for this send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder recipientBcc(String recipientBcc, String... recipientsBcc) {
            // Prepare the list.
            List<String> recipients = new ArrayList<>(1 + recipientsBcc.length);
            recipients.add(recipientBcc);
            recipients.addAll(Arrays.asList(recipientsBcc));
            // Set the list.
            this.recipientBcc = recipients;
            return this;
        }

        /**
         * You can specify a list with email addresses that will be used as bcc
         * for this email send.
         *
         * @param recipientBcc the list with email addresses that will be used
         * as bcc for this email send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder recipientBcc(List<String> recipientBcc) {
            this.recipientBcc = recipientBcc;
            return this;
        }

        /**
         * You can specify one or more email address that will be used as cc
         * recipients.
         *
         * @param attachment the first attachment.
         * @param attachments the other attachments for this send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder attachments(String attachment, String... attachments) {
            // Prepare the list.
            List<String> attachmentsToUse = new ArrayList<>(1 + attachments.length);
            attachmentsToUse.add(attachment);
            attachmentsToUse.addAll(Arrays.asList(attachments));
            // Set the list.
            this.attachments = attachmentsToUse;
            return this;
        }

        /**
         * You can specify a list with email attachments that will be used for
         * this email send.
         *
         * @param attachments the list with email attachments that will be used
         * for this email send.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder attachments(List<String> attachments) {
            this.attachments = attachments;
            return this;
        }

        /**
         * The body of the email message.
         *
         * @param message the body of the email message.
         * @return the builder for chain usage.
         */
        public ExchangeClientBuilder message(String message) {
            this.message = message;
            return this;
        }

        /**
         * Build a mail.
         *
         * @return an EmailApacheUtils object.
         */
        public ExchangeClient build() {
            return new ExchangeClient(this);
        }
    }

    public boolean sendExchange() {
        // The Exchange Server Version.
        ExchangeService exchangeService = new ExchangeService(exchangeVersion);

        // Credentials to sign in the MS Exchange Server.
        ExchangeCredentials exchangeCredentials = new WebCredentials(username, password, domain);
        exchangeService.setCredentials(exchangeCredentials);

        // URL of exchange web service for the mailbox.
        try {
            exchangeService.setUrl(new URI("https://" + hostname + "/ews/Exchange.asmx"));
        } catch (URISyntaxException ex) {
            LOGGER.error("An exception occured while creating the uri for exchange service.", ex);
            return false;
        }

        // The email.
        EmailMessage emailMessage;
        try {
            emailMessage = new EmailMessage(exchangeService);
            emailMessage.setSubject(subject);
            emailMessage.setBody(MessageBody.getMessageBodyFromText(message));
        } catch (Exception ex) {
            LOGGER.error("An exception occured while setting the email message.", ex);
            return false;
        }

        // TO recipient.
        try {
            emailMessage.getToRecipients().add(recipientTo);
        } catch (ServiceLocalException ex) {
            LOGGER.error("An exception occured while sstting the TO recipient(" + recipientTo + ").", ex);
            return false;
        }

        // CC recipient.
        for (String recipient : recipientCc) {
            try {
                emailMessage.getCcRecipients().add(recipient);
            } catch (ServiceLocalException ex) {
                LOGGER.error("An exception occured while sstting the CC recipient(" + recipient + ").", ex);
                return false;
            }
        }

        // BCC recipient
        for (String recipient : recipientBcc) {
            try {
                emailMessage.getBccRecipients().add(recipient);
            } catch (ServiceLocalException ex) {
                LOGGER.error("An exception occured while sstting the BCC recipient(" + recipient + ").", ex);
                return false;
            }
        }

        // Attachements.
        for (String attachmentPath : attachments) {
            try {
                emailMessage.getAttachments().addFileAttachment(attachmentPath);
            } catch (ServiceLocalException ex) {
                LOGGER.error("An exception occured while setting the attachment.", ex);
                return false;
            }
        }

        try {
            emailMessage.send();
            LOGGER.debug("An email is send.");
        } catch (Exception ex) {
            LOGGER.error("An exception occured while sending an email.", ex);
            return false;
        }

        return true;
    }

}

Un exemple de travail,

// import Microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion;
ExchangeClient client = new ExchangeClient.ExchangeClientBuilder()
        .hostname("webmail.domainOfWeb.com")
        .exchangeVersion(ExchangeVersion.Exchange2010)
        .domain("ActiveDirectoryDomain")
        .username("ActiveDirectoryUsername")
        .password("ActiveDirectoryPassword")
        .recipientTo("[email protected]")
        .recipientCc("[email protected]") // Ignore it in case you will not use Cc recipients.
        .recipientBcc("[email protected]") // Ignore it in case you will not use Bcc recipients.
        .attachments("/home/username/image.png") // Ignore it in case you will not use attachements.
        .subject("Test Subject")
        .message("Test Message")
        .build();
client.sendExchange();
1

Veuillez utiliser les éléments de code suivants au lieu de Transport.send(message);

MimeMessage message = new MimeMessage(session);

message.saveChanges();
Transport transport = session.getTransport("smtp");
transport.connect(Host, "user", "pwd");
transport.sendMessage(message, message.getAllRecipients());
transport.close();

J'ai testé au local et ça marche

0
Ming Jiang