Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it L'avatar di Alex80b
    Registrato dal
    Feb 2004
    Messaggi
    155

    [JSP/Java] Invio mail con office 365

    Ciao,
    sto cercando di fare inviare delle mail utilizzando Office 365. La connessione sembra avvenire correttamente, ma poi mi ritorna un errore di autenticazione: javax.servlet.ServletException: javax.mail.AuthenticationFailedException

    user e password sono sicuramente corretti visto che da outlook mi connetto senza problemi.

    Vi riporto il codice che ho scritto in modo che magari trovate qualche cavolata che ho scritto. Grazie a chi mi darà una mano!

    codice:
    Properties props = new Properties(); String user = "mail mittente";
     String password = "password";
     
    // Set debug so we see the whole communication with the server
    props.put("mail.debug", "true");
    
    
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.host", outgoingHost);
    props.put("mail.smtp.auth", "true");
    props.put("mail.smtp.port", "587");
    
    
    // Enable STARTTLS
    props.put("mail.smtp.starttls.enable", "true");
    
    
    // Accept only TLS 1.1 and 1.2
    props.setProperty("mail.smtp.ssl.protocols", "TLSv1.1 TLSv1.2");
    
    
    Session session1 = Session.getInstance(props, null);
    session1.setDebug(true);
    
    
    // Create an SMTP transport from the session
        SMTPTransport t = (SMTPTransport)session1.getTransport("smtp");
    
    
    // Connect to the server using credentials
        t.connect(outgoingHost, user, password);
    
    
           MimeMessage message = new MimeMessage(session1);
            message.setSubject("AATMI - Credenziali - MIS_MI - RESET");
            message.setContent(testo, "text/plain");
    
    
        MimeMultipart mp = new MimeMultipart();
                MimeBodyPart body = new MimeBodyPart();
                body.setText(testo, "iso-8859-1", "html");
                mp.addBodyPart(body);
    
    
        String filename =  directory + "allegato.xls";
            FileDataSource source = new FileDataSource(filename);
            attachment.setDataHandler(new DataHandler(source));    
            attachment.setFileName("allegato.xls");
            mp.addBodyPart(attachment);
            message.setContent(mp);
          
            message.addRecipient(Message.RecipientType.TO, 
            new InternetAddress("mail di destinazione"));
    
    
    t.sendMessage(message, message.getAllRecipients());
    [CODE]

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,181
    Qui la configurazione che uso io (ometto, ovviamente, utente e password):

    codice:
    mail.smtp.host = smtp-mail.outlook.com
    mail.smtp.starttls.enable = true
    mail.smtp.auth = true
    mail.smtp.port = 587
    mail.smtp.connectiontimeout = 30000
    mail.smtp.timeout = 30000

    Fine.

    Prova a rimuovere queste che non credo siano corrette:

    codice:
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.host", outgoingHost);
    Ultima modifica di LeleFT; 25-03-2021 a 12:35
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it L'avatar di Alex80b
    Registrato dal
    Feb 2004
    Messaggi
    155
    Quote Originariamente inviata da LeleFT Visualizza il messaggio
    Qui la configurazione che uso io (ometto, ovviamente, utente e password):

    codice:
    mail.smtp.host = smtp-mail.outlook.com
    mail.smtp.starttls.enable = true
    mail.smtp.auth = true
    mail.smtp.port = 587
    mail.smtp.connectiontimeout = 30000
    mail.smtp.timeout = 30000

    Fine.

    Prova a rimuovere queste che non credo siano corrette:

    codice:
    props.put("mail.transport.protocol", "smtp");
    props.put("mail.host", outgoingHost);
    Ho fatto la prova da te indicata, ma non è cambiato nulla.

    Lo stesso codice funzionava su un account gmail (ovviamente con differente host e porta), mentre con i parametri per office365 non va...

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,181
    Questa è una classettina che mi sono scritto per le applicazioni "veloci":
    codice:
    import java.io.FileInputStream;
    import java.util.*;
    import javax.activation.DataHandler;
    import javax.mail.*;
    import javax.mail.internet.*;
    import javax.mail.util.ByteArrayDataSource;
    import org.apache.log4j.*;
    
    public class MailerUtility {
    
        // Logger
        private static Logger logger = Logger.getLogger(MailerUtility.class.getName());
    
        // User Authenticator
        private class UserAuthenticator extends Authenticator {
    
            private String user;
            private String pass;
    
            public UserAuthenticator(String user, String pass) {
                this.user = user;
                this.pass = pass;
            }
    
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(user, pass);
            }
        }
    
        // Classe che rappresenta un allegato
        private class Allegato {
    
            private String nomeAllegato;
            private String mimeType;
            private String cid;
            private byte[] fileAllegato;
    
            public Allegato(String nomeAllegato, String mimeType, String cid, byte[] fileAllegato) {
                this.nomeAllegato = nomeAllegato;
                this.mimeType = mimeType;
                this.cid = cid;
                this.fileAllegato = fileAllegato;
            }
    
            public String getNomeAllegato() {
                return nomeAllegato;
            }
    
            public String getMimeType() {
                return mimeType;
            }
            
            public String getCid() {
                return cid;
            }
            
            public byte[] getFileAllegato() {
                return fileAllegato;
            }
        }
    
        private String mailConfig;                  // Percorso al file di configurazione
        private String subject;                     // Oggetto della mail
        private String txtMessage;                  // Corpo del messaggio in formato testo
        private String htmlMessage;                 // Corpo del messaggio in formato HTML
        private ArrayList<String> toAddress;        // Elenco destinatari principali
        private ArrayList<String> ccAddress;        // Elenco destinatari in copia
        private ArrayList<String> bccAddress;       // Elenco destinatari in copia nascosta
        private ArrayList<String> replyTo;          // Elenco destinatari delle risposte
        private ArrayList<Allegato> attachments;    // Elenco allegati
        private boolean retrySend;                  // Flag che indica che può essere tentato il reinvio in caso di errore
        private int numRetry;                       // Numero di tentativi effettuati di reinvio
    
        public MailerUtility(String mailConfig) {
            this.mailConfig = mailConfig;
            subject = "";
            txtMessage = "";
            htmlMessage = "";
            
            retrySend = false;
            numRetry = 0;
    
            toAddress = new ArrayList<String>();
            ccAddress = new ArrayList<String>();
            bccAddress = new ArrayList<String>();
            replyTo = new ArrayList<String>();
            attachments = new ArrayList<Allegato>();
        }
    
        public void setSubject(String subject) {
            this.subject = subject;
        }
    
        public void addRecipient(String recipient) {
            toAddress.add(recipient);
        }
    
        public void addCopyRecipient(String copyRec) {
            ccAddress.add(copyRec);
        }
    
        public void addHiddenCopyRecipient(String hideRec) {
            bccAddress.add(hideRec);
        }
    
        public void addReplyTo(String addr) {
            replyTo.add(addr);
        }
    
        public void addAttachment(byte[] f, String newName, String mimeType, String cid) {
            attachments.add(new Allegato(newName, mimeType, cid, f));
        }
    
        public void setTextMessage(String txtMsg) {
            this.txtMessage = txtMsg;
        }
        
        public void setHtmlMessage(String htmlMessage) {
            this.htmlMessage = htmlMessage;
        }
    
        public boolean sendMail() {
            boolean ret = false;
            retrySend = false;
            try {
                Properties specProps = new Properties();
                
                // Impostiamo un timeOut per la connessione
                // 30 secondi sono più che sufficienti
                specProps.put("mail.smtp.connectiontimeout", "30000");
                specProps.put("mail.smtp.timeout", "30000");
                
                // Andiamo a leggere la configurazione per la connessione al server SMTP
                specProps.load(new FileInputStream(mailConfig));
    
                String user = specProps.getProperty("nomeutente");
                String pass = specProps.getProperty("password");
                specProps.remove("nomeutente");
                specProps.remove("password");
                
                UserAuthenticator userAuthenticator = new UserAuthenticator(user, pass);
                Session session = Session.getInstance(specProps, userAuthenticator);
    
                MimeMessage message = new MimeMessage(session);
    
                InternetAddress iaFrom = new InternetAddress( user );
                message.setFrom( iaFrom );
    
                if (!replyTo.isEmpty()) {
                    Address[] addrReply = new Address[replyTo.size()];
                    for (int i = 0; i < replyTo.size(); i++) {
                        addrReply[i] = new InternetAddress(replyTo.get(i));
                    }
    
                    message.setReplyTo(addrReply);
                }
    
    
                // Aggiungo i destinatari visibili
                for (String rec : toAddress) {
                    message.addRecipient(Message.RecipientType.TO, new InternetAddress(rec));
                }
    
                // Aggiungo i destinatari in copia
                for (String rec : ccAddress) {
                    message.addRecipient(Message.RecipientType.CC, new InternetAddress(rec));
                }
    
                // Aggiungo i destinatari in copia nascosta
                for (String rec : bccAddress) {
                    message.addRecipient(Message.RecipientType.BCC, new InternetAddress(rec));
                }
    
                message.setSubject(subject);
    
                componiMessaggio(message);
    
                Transport.send(message);
                
                ret = true;
            } catch (AuthenticationFailedException afe) {
                if (numRetry < 2) {
                    logger.error("Errore autenticazione, ma dovrebbe essere un falso allarme! Riprovo.", afe);
                    
                    retrySend = true;
                    numRetry++;
                } else {
                    logger.error("Sembra esserci per davvero un problema di autenticazione.", afe);
                    
                    retrySend = false;
                    numRetry++;
                }
            } catch (AddressException ae) {
                logger.error("Errore invio mail a causa di un indirizzo errato.", ae);
            } catch (MessagingException me) {
                if (numRetry < 2) {
                    if ( me.getMessage().startsWith("Exception reading response") ) {
                        logger.error("Errore di timeout in lettura response dal server, ma potrebbe essere un falso allarme! Riprovo.", me);
    
                        retrySend = true;
                        numRetry++;
                    } else {
                        logger.error("Sembra esserci per davvero un problema di comunicazione col server di posta.", me);
                        
                        retrySend = false;
                        numRetry++;
                    }
                } else {
                    logger.error("Sembra esserci per davvero un problema di comunicazione col server di posta.", me);
                    
                    retrySend = false;
                    numRetry++;
                }
            } catch (Exception e) {
                logger.error("Errore invio mail generico.", e);
            }
            
            return ret;
        }
        
        public boolean canRetrySend() {
            return retrySend;
        }
        
        private void componiMessaggio(MimeMessage message) throws Exception {
            Multipart multipart = new MimeMultipart();
    
            // Se c'è anche una parte HTML, devo generare un multipart alternative
            if ((htmlMessage != null) && !"".equals(htmlMessage)) {
                MimeBodyPart altBody = new MimeBodyPart();
    
                Multipart alternative = new MimeMultipart("alternative");
    
                MimeBodyPart textBodyPart = new MimeBodyPart();
                textBodyPart.setText(txtMessage, "ISO-8859-15");
    
                MimeBodyPart htmlBodyPart = new MimeBodyPart();
                
                htmlBodyPart.setContent(htmlMessage, "text/html; charset=utf-8");
                htmlBodyPart.addHeader("Content-Transfer-Encoding", "7bit");
    
                alternative.addBodyPart(textBodyPart);
                alternative.addBodyPart(htmlBodyPart);
    
                altBody.setContent(alternative);
                multipart.addBodyPart(altBody);
            } else {
                // Creo il corpo del messaggio con il testo
                BodyPart bodyPart = new MimeBodyPart();
                ((MimeBodyPart) bodyPart).setText(txtMessage, "ISO-8859-15");
    
                multipart.addBodyPart(bodyPart);
            }
            
            // Se ci sono allegati, li allego ;-)
            for (Allegato al : attachments) {
                ByteArrayDataSource bds = new ByteArrayDataSource(al.getFileAllegato(), al.getMimeType());
                MimeBodyPart bodyPart = new MimeBodyPart();
                
                bodyPart.setDataHandler( new DataHandler(bds) );
                bodyPart.setFileName(al.getNomeAllegato());
    
                if ( !"".equals(al.getCid().trim()) ) {
                    bodyPart.setDisposition( MimeBodyPart.INLINE );
                    bodyPart.setHeader("Content-ID","<" + al.getCid().trim() + ">");
                }
                
                multipart.addBodyPart(bodyPart);
            }
    
            // Aggiungo il Multipart al messaggio
            message.setContent(multipart);
        }
    }

    In questo caso ho usato Log4J per il logging, ma se non ti serve puoi tirarlo via.
    Utilizza un file di properties per la configurazione, così:
    codice:
    mail.smtp.host = smtp-mail.outlook.com
    mail.smtp.starttls.enable = true
    mail.smtp.auth = true
    mail.smtp.port = 587
    mail.smtp.connectiontimeout = 30000
    mail.smtp.timeout = 30000
    nomeutente = <tuo indirizzo email>
    password = <tua password>

    Qui un esempio d'uso:
    codice:
    // Creo l'istanza passandogli il percorso al file di properties
    MailerUtility mu = new MailerUtility("/percorso/al/tuo/file/di/properties");
    
    // Aggiungo tutti i destinatari principali (sono facoltativi)
    mu.addRecipient("pippo@pluto.it");
    
    // Aggiungo tutti i destinatari in copia (sono facoltativi)
    mu.addCopyRecipient("paperone@pluto.it");
    
    // Aggiungo i destinatari in copia nascosta (sono facoltativi)
    mu.addHiddenCopyRecipient("paperina@pluto.it");
    
    // Aggiunto l'indirizzo per il Reply-to (è facoltativo)
    mu.addReplyTo("paperino@pluto.it");
    
    // Oggetto della mail
    mu.setSubject("Bla bla bla");
    
    // Il corpo della mail in formato solo testo (è facoltativo, se c'è l'HTML)
    mu.setTextMessage("Corpo della mail");
    
    // Il corpo della mail in formato HTML (è facoltativo se c'è il formato testo)
    mu.setHtmlMessage("<p>Corpo della mail</p>");
    
    // Eventuali allegati
    byte[] fileData = ... // Leggo il file e ottengo un array di byte
    mu.addAttachment(fileData, "MioFile.PDF", "application/pdf", "");
    
    // Invio la mail
    boolean esito = false;
    do {
       esito = mu.sendMail();
                
       if ( !esito && mu.canRetrySend()) {
          try {
             Thread.sleep( 10000L );   // Attendiamo 10 secondi prima di ritentare l'invio
          } catch (InterruptedException ie) { }
       }
    } while(!esito && mu.canRetrySend());

    Questo codice (in realtà è una semplificazione, ma non cambia) lo sto usando in produzione ormai da 2 anni (quando abbiamo fatto il passaggio a Office 365).

    Ciao.
    Ultima modifica di LeleFT; 25-03-2021 a 14:58
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it L'avatar di Alex80b
    Registrato dal
    Feb 2004
    Messaggi
    155
    Grazie a tutti!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.