一、注册应用程序
1、登录Azure门户
地址:https://portal.azure.com/#home
选择Microsoft Entra ID
2、添加应用
点击右侧管理(Manage)->应用注册(app registration)->添加应用(new registration)
应用添加完后记录自己的应用ID(clientId)、租户ID(tenantId)。
clientId和tenantId收发邮件时用
注册应用后去首页概述-企业应用程序下搜索获取ObjectId
ObjectId在后面注册Exchange时能用到
3、添加客户端密码
点击证书或密码添加客户端密码(clientSecret),注意这个客户端密码只有创建的时候能看到,所以得保存下来
二、API权限授权
1、勾选权限
点击api权限->添加权限->我的组织使用的 API->搜索Office 365 Exchange Online,将IMAP、POP、SMTP都勾选上。
2、管理员授权
使用【全局管理员】角色的账号登录,对这些权限授权
三、在 Exchange 中注册服务主体
1、连接ExchangeOnline
本地电脑打开PowerShell
依次执行命令
Install-Module -Name ExchangeOnlineManagement
Import-module ExchangeOnlineManagement
Connect-ExchangeOnline -Organization <上文的tenantId>
执行后登录管理员的邮箱账号
如果遇到:Import-Module : 无法加载文件,因为在此系统上禁止运行脚本
执行:set-ExecutionPolicy RemoteSigned
选择:Y
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、收件
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);
}
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);
}