一、注册应用程序

1、登录Azure门户

地址: https://portal.azure.com/#home

选择Microsoft Entra ID

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_SMTP

2、添加应用

点击右侧管理(Manage)->应用注册(app registration)->添加应用(new registration)

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_outlook邮箱_02

应用添加完后记录自己的应用ID(clientId)、租户ID(tenantId)和ObjectId。

ObjectId在后面注册Exchange时能用到

clientId和tenantId收发邮件时用

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_office365邮箱_03

3、添加客户端密码

点击证书或密码添加客户端密码(clientSecret),注意这个客户端密码只有创建的时候能看到,所以得保存下来

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_outlook邮箱_04

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_SMTP_05

二、API权限授权

1、勾选权限

点击api权限->添加权限->我的组织使用的 API->搜索Office 365 Exchange Online,将IMAP、POP、SMTP都勾选上。

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_IMAP_06

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_IMAP_07

2、管理员授权

使用【全局管理员】角色的账号登录,对这些权限授权

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_SMTP_08

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_outlook邮箱_09

三、在 Exchange 中注册服务主体

1、连接ExchangeOnline

本地电脑打开PowerShell

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_outlook邮箱_10

依次执行命令

Install-Module -Name ExchangeOnlineManagement

Import-module ExchangeOnlineManagement

Connect-ExchangeOnline -Organization <上文的tenantId>

执行后登录管理员的邮箱账号

如果遇到:Import-Module : 无法加载文件,因为在此系统上禁止运行脚本

执行:set-ExecutionPolicy RemoteSigned

选择:Y

outlook邮箱(office365)使用java进行收取(IMAP)和发送(SMTP)_outlook邮箱_11

2、给邮箱授权

查看服务主体

New-ServicePrincipal -AppId <上文的clientId> -ObjectId <上文的ObjectId>

给需要IMAP和SMTP的邮箱授权:

Add-MailboxPermission -Identity "xxx@xxx.com" -User <上文的ObjectId> -AccessRights FullAccess

至此所有准备工作完成,开始撸代码

四、获取token

/*   /***
     * 获取office365邮箱的登录令牌
     * @param otherParam
     * 格式为json:{"tenantId":"租户ID","clientId":"客户端ID","clientSecret":"客户端密码"}
     * @return
     */
    private static String getOffice365Token(String otherParam){
        if(StringUtils.isBlank(otherParam)){
            throw new RuntimeException("参数配置错误!");
        }
        try {
            JSONObject otherObj = JSONObject.parseObject(otherParam);
            // 租户ID
            String tenantId = otherObj.getString("tenantId");
            // 客户端ID
            String clientId = otherObj.getString("clientId");
            String clientSecret = otherObj.getString("clientSecret");

            CloseableHttpClient client = HttpClients.createDefault();
            HttpPost loginPost = new HttpPost("https://login.microsoftonline.com/" + tenantId + "/oauth2/v2.0/token");
            String scopes = "https://outlook.office365.com/.default";
            String encodedBody = "client_id=" + clientId + "&scope=" + scopes + "&client_secret=" + clientSecret
                    + "&grant_type=client_credentials";
            loginPost.setEntity(new StringEntity(encodedBody, ContentType.APPLICATION_FORM_URLENCODED));
            loginPost.addHeader(new BasicHeader("cache-control", "no-cache"));
            CloseableHttpResponse loginResponse = client.execute(loginPost);
            InputStream inputStream = loginResponse.getEntity().getContent();
            String resp = IOUtils.toString(inputStream);
            return JSONObject.parseObject(resp).getString("access_token");
        } catch (Exception e) {
            throw new RuntimeException("参数配置错误,office365邮箱获取token失败!", e);
        }
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

五、邮件收取和发送

1、收件
private static void receiveImap() throws Exception {
    Properties properties = new Properties();
    properties.put("mail.imap.auth", true);
    properties.put("mail.imap.ssl.enable", true);
    properties.put("mail.imap.starttls.enable", true);
    properties.put("mail.imap.auth.mechanisms", "XOAUTH2");
    Session session = Session.getInstance(properties);
    session.setDebug(true);
    Store store = session.getStore("imap");
    String token = getOffice365Token("{\"tenantId\":\"租户ID\",\"clientId\":\"客户端ID\",\"clientSecret\":\"客户端密码\"}");
    store.connect("outlook.office365.com", "xxx@xxx.com", token);

    //收件邮箱
    Folder inboxFolder = store.getFolder("Inbox");
    inboxFolder.open(Folder.READ_ONLY);
    Message[] messages = inboxFolder.getMessages();
    IMAPMessage msg = (IMAPMessage) messages[messages.length - 1];
    System.out.println(msg);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
2、发件
private static void sendSmtp() throws Exception {
    //构建Session Properties
    Properties properties = new Properties();
    properties.put("mail.smtp.host", "smtp.office365.com");
    properties.put("mail.smtp.port", 587);
    properties.put("mail.transport.protocol", "smtp");
    properties.put("mail.smtp.auth", true);
    properties.put("mail.debug", true);
    properties.put("mail.smtp.ssl.enable", false);
    properties.put("mail.smtp.starttls.enable", true);
    properties.put("mail.smtp.auth.xoauth2.disable", false);
    properties.put("mail.smtp.auth.mechanisms", "XOAUTH2");
    properties.put("mail.smtp.auth.login.disable", true);
    properties.put("mail.smtp.auth.plain.disable", true);
    String token = getOffice365Token("{\"tenantId\":\"租户ID\",\"clientId\":\"客户端ID\",\"clientSecret\":\"客户端密码\"}");
    Session session = Session.getInstance(properties, new Authenticator() {
        @Override
        protected PasswordAuthentication getPasswordAuthentication() {
            return new PasswordAuthentication("xxx@xxx.com", token);
        }
    });
    session.setDebug(true);

    String html = "<p>您好:</p><p>这是一封系统测试邮件,请忽略!</p><p>祝好!</p>";
    MimeMessage msg = new MimeMessage(session);
    msg.setSubject("测试邮件发送", "UTF-8");
    msg.setFrom(new InternetAddress("xxx<xxx@xxx.com>"));
    msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse("receiver@xxx.com"));
    MimeMultipart cover = new MimeMultipart("mixed");
    MimeBodyPart bodyPart = new MimeBodyPart();
    bodyPart.setContent(html, "text/html; charset=utf-8");
    cover.addBodyPart(bodyPart);
    // 附件
    MimeBodyPart attachmentPart = new MimeBodyPart();
    DataHandler dataHandler = new DataHandler(new URL("http://附件url"));
    attachmentPart.setDataHandler(dataHandler);
    attachmentPart.setContentID(null);
    attachmentPart.setFileName(MimeUtility.encodeText("附件.pdf"));
    cover.addBodyPart(attachmentPart);
    msg.setContent(cover);
    msg.setSentDate(new Date());
    Transport.send(msg);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

六、微软官网文档

 https://learn.microsoft.com/zh-cn/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth