问题
Mail service configuration in standalone-full-ha.xml
.
<subsystem xmlns="urn:jboss:domain:mail:2.0">
<mail-session name="default" jndi-name="java:jboss/mail/Default" from="sender@gmail.com">
<smtp-server outbound-socket-binding-ref="mail-smtp" ssl="true" username="User" password="password"/>
</mail-session>
</subsystem>
The mail Session
in turn references an SMTP host bound at localhost at port 465.
<outbound-socket-binding name="mail-smtp">
<remote-destination host="smtp.gmail.com" port="465"/>
</outbound-socket-binding>
The actual password used in the configuration is an application specific password generated during "2-Step Verification" at https://security.google.com/settings/security/apppasswords
After this configuration has been made, an attempted to send an email using the following code causes an exception to be thrown.
@Resource(mappedName = "java:jboss/mail/Default")
private Session mailSession;
public void init() throws AddressException, MessagingException {
MimeMessage m = new MimeMessage(mailSession);
Address from = new InternetAddress("sender@gmail.com");
Address[] to = new InternetAddress[]{new InternetAddress("receiver@gmail.com")};
m.setFrom(from);
m.setRecipients(Message.RecipientType.TO, to);
m.setSubject("Message Subject");
m.setSentDate(new Date());
m.setContent("Mail sent from app", "text/html");
Transport.send(m);
}
The following exception is thrown.
07:48:36,906 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-9) #{countryManagedBean.init}: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/answer/14257 t70sm5413631pfi.8 - gsmtp
: javax.faces.FacesException: #{countryManagedBean.init}: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/answer/14257 t70sm5413631pfi.8 - gsmtp
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UIViewAction.broadcast(UIViewAction.java:562)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:78)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.websockets.jsr.JsrWebSocketFilter.doFilter(JsrWebSocketFilter.java:151)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:128)
at org.omnifaces.facesviews.FacesViewsForwardingFilter.doFilter(FacesViewsForwardingFilter.java:89)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at filter.NoCacheFilter.doFilter(NoCacheFilter.java:33)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at org.omnifaces.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:122)
at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108)
at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132)
at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.DisableCacheHandler.handleRequest(DisableCacheHandler.java:33)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:282)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: javax.faces.el.EvaluationException: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/answer/14257 t70sm5413631pfi.8 - gsmtp
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 57 more
Caused by: javax.mail.AuthenticationFailedException: 535-5.7.8 Username and Password not accepted. Learn more at
535 5.7.8 https://support.google.com/mail/answer/14257 t70sm5413631pfi.8 - gsmtp
at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:892)
at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:814)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:728)
at javax.mail.Service.connect(Service.java:386)
at javax.mail.Service.connect(Service.java:245)
at javax.mail.Service.connect(Service.java:194)
at javax.mail.Transport.send0(Transport.java:253)
at javax.mail.Transport.send(Transport.java:124)
at admin.bean.CountryManagedBean.init(CountryManagedBean.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.sun.el.parser.AstValue.invoke(AstValue.java:292)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 58 more
Using WildFly 9.0.2 final (the application using a self-signed SSL certificate should not be an issue here).
回答1:
There is a configuration mistake made in an incorrect assumption. The XML attribute username
expects the actual email address where the screen name of the corresponding sender's account was given hence, the exception. It works fine after it has been corrected as follows.
<mail-session name="default" jndi-name="java:jboss/mail/Default" from="sender@gmail.com">
<smtp-server outbound-socket-binding-ref="mail-smtp" ssl="true" username="sender@gmail.com" password="password"/>
</mail-session>
The actual password to be used in the configuration is an application specific password generated during "2-Step Verification" at https://security.google.com/settings/security/apppasswords
as already stated in the question.
The mail session javax.mail.Session
can then be injected into any Java EE artifact like Servlets, Servlet filters, managed beans, EJBs, Message Driven Beans (MDB) etc using the javax.annotation.Resource
annotation.
One thing which does not happen for some unknown reasons is the sender's name (label) as specified with the from
XML attribute. It always sends the sender's email address as the sender name which is unexpected. Even doing,
Address from = new InternetAddress("admin@server.domain");
mimeMessage.setFrom(from);
does not help. I followed some patterns as suggested in this answer but it did not help either. It however, works in Java SE environment. It is nevertheless a different thing than the current question. Perhaps, I will ask a separate question later on.
Additional :
I prefer JMS queues to send mails asynchronously as a background process, since sending a mail may be delayed significantly for many reasons. The actual message along with the recipient's email address is sent through a JMS queue and the actual mail is delivered to a target mail server from within the receiving terminal of the corresponding queue like the following.
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:jboss/exported/jms/emailQueue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})
@RunAs("ROLE_ADMIN")
public class MailBean implements MessageListener {
@Resource(lookup = "java:jboss/mail/Default")
private Session mailSession; // javax.jms.Session
@Override
@PermitAll
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public void onMessage(Message message) {
try {
if (message instanceof ObjectMessage) {
ObjectMessage objectMessage = (ObjectMessage) message;
EmailUtil emailUtil = (EmailUtil) objectMessage.getObject();
String receiver = emailUtil.getReceiver();
String textMessage = emailUtil.getMessage();
if (StringUtils.isNotBlank(receiver) && StringUtils.isNotBlank(textMessage)) {
MimeMessage mimeMessage = new MimeMessage(mailSession);
Address[] to = new InternetAddress[]{new InternetAddress(receiver)};
mimeMessage.setRecipients(javax.mail.Message.RecipientType.TO, to);
mimeMessage.setSubject(emailUtil.getSubject(), "UTF-8");
mimeMessage.setSentDate(new Date());
mimeMessage.setText(textMessage, "UTF-8", "html");
Transport.send(mimeMessage);
} else {
System.out.println("No message found.");
}
} else {
System.out.println("Message is of wrong type : " + message.getClass().getName());
}
} catch (JMSException | MessagingException e) {
Logger.getLogger(MailBean.class.getName()).log(Level.SEVERE, null, e);
}
}
}
EmailUtil
is a utility Java class holding necessary properties and implementing the java.io.Serializable
interface (which is mandatory for sending serializable Java objects).
public final class EmailUtil implements Serializable {
private String message;
private String subject;
private String receiver;
private static final long serialVersionUID = 1L;
// Constructor(s) + getters + setters + hashCode() + equals() + toString().
}
In order to inject a Queue
, I use an application scoped CDI managed bean for better reusability on the front side.
@ApplicationScoped
public class EmailQueueBean {
@Resource(lookup = "java:jboss/exported/jms/emailQueue")
private Queue queue;
@Resource(lookup = "java:jboss/exported/jms/emailFactory")
private ConnectionFactory connectionFactory;
public EmailQueueBean() {}
public void send(EmailUtil emailUtil) throws JMSException {
try (Connection connection = connectionFactory.createConnection("admin@gmail.com", "admin_password");
javax.jms.Session session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(queue)) {
ObjectMessage objectMessage = session.createObjectMessage(emailUtil);
producer.send(objectMessage);
}
}
}
Inject this bean anywhere in any Java EE artifact, construct an instance of EmailUtil
manually using new
and invoke the send()
method on behalf of the injected proxy instance of the managed bean passing through the instance of EmailUtil
constructed.
The authentication using username
/ password
as specified with the createConnection()
method is not needed (nor @RunAs("ROLE_ADMIN")
before the MDB), in case the security is disabled / not used in the hornetq server in the configuration.
See also :
- JAAS authentication in JMS using WildFly : javax.jms.JMSSecurityException: HQ119032: User: null doesnt have permission=SEND on address {2}
来源:https://stackoverflow.com/questions/34780686/javax-mail-authenticationfailedexception-535-5-7-8-username-and-password-not-ac