javax.mail.AuthenticationFailedException:535-5.7.8不接受用户名和密码

时间:2016-01-14 02:27:38

标签: email java-ee gmail javamail wildfly

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>

邮件Session依次引用绑定在localhost端口465的SMTP主机。

<outbound-socket-binding name="mail-smtp">
    <remote-destination host="smtp.gmail.com" port="465"/>
</outbound-socket-binding>

配置中使用的实际密码是在&#34; 2-Step Verification&#34;期间生成的应用专用密码。在https://security.google.com/settings/security/apppasswords

完成此配置后,尝试使用以下代码发送电子邮件会导致抛出异常。

@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);
}

抛出以下异常。

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

使用WildFly 9.0.2 final(使用自签名SSL证书的应用程序不应该成为问题)。

1 个答案:

答案 0 :(得分:1)

在错误的假设中存在配置错误。 XML属性username需要实际的电子邮件地址,其中给出了相应发件人帐户的屏幕名称,例外情况。经过如下修正后,它可以正常工作。

<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>

配置中使用的实际密码是在https://security.google.com/settings/security/apppasswords的“两步验证”期间生成的应用专用密码,如问题中所述。

然后可以使用javax.mail.Session注释将邮件会话javax.annotation.Resource注入任何Java EE工件,如Servlet,Servlet过滤器,托管bean,EJB,消息驱动Bean(MDB)等。

由于某些未知原因而未发生的一件事是使用from XML属性指定的发件人姓名(标签)。它始终将发件人的电子邮件地址作为发件人姓名发送,这是意外的。即使这样做,

Address from = new InternetAddress("admin@server.domain");
mimeMessage.setFrom(from);

没有帮助。我遵循了this answer中建议的一些模式,但它也没有帮助。但是,它适用于Java SE环境。然而,与当前问题不同的是它。也许,我稍后会问一个单独的问题。

其他:

我更喜欢JMS队列作为后台进程异步发送邮件,因为发送邮件可能会由于多种原因而显着延迟。实际邮件和收件人的电子邮件地址通过JMS队列发送,实际邮件从相应队列的接收终端内传送到目标邮件服务器,如下所示。

@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是一个实用程序Java类,它包含必要的属性并实现java.io.Serializable接口(这对于发送可序列化的Java对象是必需的)。

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().
}

为了注入Queue,我使用应用程序作用域的CDI托管bean,以便在正面提供更好的可重用性。

@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);
        }
    }
}

在任何Java EE工件中的任何位置注入此bean,使用EmailUtil手动构造new实例,并代表托管bean传入的注入代理实例调用send()方法通过构造EmailUtil的实例。

如果禁用安全性,则不需要使用username方法指定的password / createConnection()进行身份验证(在MDB之前也不需要@RunAs("ROLE_ADMIN"))用于配置中的hornetq服务器。

另见: