如何使用带有OAuth2身份验证的Gmail SMTP发送带有java邮件的邮件?

时间:2015-09-28 20:23:18

标签: java oauth-2.0 smtp javamail google-oauth

我阅读了下面的链接但我无法使用OAuth2身份验证机制发送邮件。谁能举个例子呢?

如果没有此身份验证,用户必须从gmail的安全设置中启用安全性较低的应用程序选项。但我不想让用户这样做。这就是我需要这种身份验证机制的原因。

link:https://java.net/projects/javamail/pages/OAuth2

1 个答案:

答案 0 :(得分:1)

以下是使用Spring在Web项目中使用OAuth2发送电子邮件的工作代码。

重要提示:

  • 首先在Google console创建项目,之后在Google控制台创建凭据时请记住设置 应用程序类型到其他。

  • 使用oauth2.py获取访问令牌和其他所需的值 码。文件本身有关于如何使用它的说明,以获得所需的值。

<强>弹簧email.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- email configuration -->
    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="smtp.gmail.com"/>
        <property name="port" value="587"/>
        <property name="username" value="xxxxxxxxxxxxx@gmail.com"/>
        <property name="password" value=""/>

        <property name="javaMailProperties">
            <props>
                <!-- Use SMTP transport protocol -->
                <prop key="mail.transport.protocol">smtp</prop>
                <!-- Use SMTP-AUTH to authenticate to SMTP server -->
                <prop key="mail.smtp.auth">true</prop>
                <!-- GMail requires OAuth to not be considered "low-security" -->
                <prop key="mail.smtp.auth.mechanisms">XOAUTH2</prop>
                <!-- Use TLS to encrypt communication with SMTP server -->
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.debug">false</prop>
            </props>
        </property>

    </bean>
    <bean id="message" class="com.upriverbank.model.Message">
        <property name="mailSender" ref="mailSender" />
    </bean>

</beans>

<强> OAuthMail.java

package com.abc.security;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.mail.javamail.JavaMailSender;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;

public class OAuthMail {


    // For using Oauth2

    private static String TOKEN_URL = "https://www.googleapis.com/oauth2/v4/token";
    private JavaMailSender sender;

    // Not a best practice to store client id, secret and token in source
    // must be stored in a file.
    private String oauthClientId = "xxxxxxxxxxxxxxxx.apps.googleusercontent.com";
    private String oauthSecret = "xxxxxxxxxxxxxxxxxxxx";
    private String refreshToken = "xxxxxxxxxxxxxxxxxxxxxxx";
    private static String accessToken = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
                                            "xxxxxxxxxxxxxxxxxxxx";
    private long tokenExpires = 1458168133864L;

    // getters and setters

    public static String getAccessToken() {
        return accessToken;
    }

    public static void setAccessToken(String accessToken) {
        accessToken = accessToken;
    }


    /*
    Renew access token if expired
     */
    public void renewToken(){

        if(System.currentTimeMillis() > tokenExpires) {

            try
            {
                String request = "client_id="+ URLEncoder.encode(oauthClientId, "UTF-8")
                        +"&client_secret="+URLEncoder.encode(oauthSecret, "UTF-8")
                        +"&refresh_token="+URLEncoder.encode(refreshToken, "UTF-8")
                        +"&grant_type=refresh_token";
                HttpURLConnection conn = (HttpURLConnection) new URL(TOKEN_URL).openConnection();
                conn.setDoOutput(true);
                conn.setRequestMethod("POST");
                PrintWriter out = new PrintWriter(conn.getOutputStream());
                out.print(request);
                out.flush();
                out.close();
                conn.connect();

                try
                {

                    HashMap<String,Object> result;
                    result = new ObjectMapper().readValue(conn.getInputStream(), new TypeReference<HashMap<String,Object>>() {});
                    accessToken = (String) result.get("access_token");
                    tokenExpires = System.currentTimeMillis()+(((Number)result.get("expires_in")).intValue()*1000);
                }
                catch (IOException e)
                {
                    String line;
                    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
                    while((line = in.readLine()) != null) {
                        System.out.println(line);
                    }
                    System.out.flush();
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}

<强> Message.java

package com.abc.model;


import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.upriverbank.security.OAuthMail;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Properties;


public class Message {


    public static final String PORT = "465";
    private static final String HOST = "smtp.gmail.com";
    private final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
    private String name;
    private String customerID;
    private String email;
    private int queryType;
    private int id;
    private String title;
    private String rStatus;
    private String query;
    private Byte isRead;
    private int customerId;
    private String password;
    private static final String BANK_SUPPORT_EMAIL = "xxxxxxx@gmail.com";


    public static String getBankSupportEmail() {
        return BANK_SUPPORT_EMAIL;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getrStatus() {
        return rStatus;
    }

    public void setrStatus(String rStatus) {
        this.rStatus = rStatus;
    }

    public String getQuery() {
        return query;
    }

    public void setQuery(String query) {
        this.query = query;
    }

    public Byte getIsRead() {
        return isRead;
    }

    public void setIsRead(Byte isRead) {
        this.isRead = isRead;
    }

    public int getCustomerId() {
        return customerId;
    }

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCustomerID() {
        return customerID;
    }

    public void setCustomerID(String customerID) {
        this.customerID = customerID;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public int getQueryType() {
        return queryType;
    }

    public void setQueryType(int queryType) {
        this.queryType = queryType;
    }




    public void viewMessage() {

    }

    public void setPassword(String password) {
        this.password = password;
    }



    private MailSender mailSender;

    public void setMailSender(MailSender mailSender) {
        this.mailSender = mailSender;
    }



   /*
      Sending an email according to provided parameters
      (sender, receiver, subject, content)
   */
    public void sendMessage(String from, String to, String subject, String msg) {


        ((JavaMailSenderImpl)this.mailSender).setPassword(OAuthMail.getAccessToken());

        SimpleMailMessage message = new SimpleMailMessage();

        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(msg);

        // sending email

        mailSender.send(message);
    }

}

<强> MessageTest.java

package com.abc.model;

import com.abc.support.spring.SpringUtil;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

    class MessageTest {

        @Test
        void sendMessage() {

            Message mm = (Message) SpringUtil.customBeanFactory("message");
            mm.sendMessage("xxxxxxx@gmail.com",
                    "xxxxxxxxx@gmail.com",
                    "Testing email",
                    "This is a testing email");
        }

    }