0

I am trying to check if SMTP settings / credentials are entered correctly for an email account using the JavaMail library. The issue I am having is that the connection is successful regardless of valid or invalid credentials.

This is being tested on a GMail account that has 3rd part app access enabled, and can be connected to via IMAP and GIMAP providers included with JavaMail. If the SMTP settings are correct then it is also capable of sending mail, I am just trying to add a layer so that when you configure a new account, the SMTP credentials and settings are tested to verify a correct configuration.

The bigger picture here is that the project this code belongs to wont only be used for GMail accounts, it should support any IMAP/SMTP email service.

I have tried a number of variations with creating Session and Transports, and primarily followed the example answer in the related questions:

Javamail transport getting success to authenticate with invalid credentials

Validate smtp server credentials using java without actually sending mail

Those answers do not appear to be working for me, as the issue is that the transport is making a successful connection with the invalid credentials, trying to send a message does fail though with a MessagingException that is not an instance of AuthenticationFailedException.. the second of those 2 related questions multiple comments claim to have a similar issue with no solution provided.

// For the purposes of this code snippet getSmtpUsername() and getSmtpPassword() return a constant string value representing the username and password to be used when logging into SMTP server.

public Authenticator getSMTPAuthenticator() {
    return new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication( getSmtpUsername(), getSmtpPassword() );
        }
    };
}

public boolean authenticateSMTP( SMTPConfiguration smtpConfiguration ) throws MessagingException {
    try {
        Properties properties = new Properties(  );
        properties.put( "mail.smtp.auth", true );
        properties.put( "mail.smtp.host", "smtp.gmail.com" );
        properties.put( "mail.smtp.port", 465 );
        properties.put( "mail.smtp.socketFactory.port", 465);
        properties.put( "mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory" );

        Transport transport = Session.getInstance( properties, getSMTPAuthenticator() ).getTransport("smtp"); //.getTransport() also has not solved this issue
        transport.connect( "smtp.gmail.com", 465, getSmtpUsername(), getSmtpPassword() );
        transport.close();
        return true;
    } catch ( AuthenticationFailedException e ) { //TODO: this exception just never happens even with wrong credentials...
        return false;
    }
}

My expected result is that if getSmtpUsername() or getSmtpPassword() return a string value that is not consistant with a valid account then the AuthenticationFailedException will be thrown, or some other method is implemented in place to determine if the credentials are incorrect.

  • Fix all these [common JavaMail mistakes](https://javaee.github.io/javamail/FAQ#commonmistakes), then post the [JavaMail debug output](https://javaee.github.io/javamail/FAQ#debug). – Bill Shannon Dec 29 '18 at 00:44
  • @BillShannon I have made the suggested changes and found out what the problem was. Thank you very much! – Black Magic Dec 31 '18 at 15:42

1 Answers1

0

After making the changes suggested by Bill Shannon it turned out the error was actually a logic error where getSmtpPassword() was returning the IMAP password (which led to successful login) under some circumstances, although the suggestions where not what solved the problem, the updated code is as follows:

public boolean authenticateSMTP( SMTPConfiguration smtpConfiguration ) throws MessagingException {
    try {
        Properties properties = new Properties(  );
        properties.put( "mail.smtp.auth", true );
        properties.put( "mail.smtp.host", "smtp.gmail.com" );
        properties.put( "mail.smtp.port", 465 );
        properties.put( "mail.smtp.ssl.enable", true);

        Transport transport = Session.getInstance( properties ).getTransport();
        transport.connect( getSmtpUsername(), getSmtpPassword() );
        transport.close();
        return true;
    } catch ( AuthenticationFailedException e ) {
        return false;
    }
}