javamail微软邮箱账号在oauth2认证方式下使用exchange协议进行发送邮件

一、在 Microsoft Entra管理中心进行应用注册获取应用程序id、租户id和密钥的值

1、应用注册
在这里插入图片描述
在这里插入图片描述

2、应用注册完成后,获取应用程序id和租户id
在这里插入图片描述
3、生成密钥,并记录密钥的值
在这里插入图片描述
密钥创建后,第一时间保存密钥的值
4、添加权限
在这里插入图片描述
在这里插入图片描述
然后需要管理员同意添加权限
在这里插入图片描述

二、废话不多说,直接上代码

package test;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Preconditions;
import microsoft.exchange.webservices.data.core.ExchangeService;
import microsoft.exchange.webservices.data.core.enumeration.misc.ConnectingIdType;
import microsoft.exchange.webservices.data.core.enumeration.misc.TraceFlags;
import microsoft.exchange.webservices.data.core.enumeration.property.BodyType;
import microsoft.exchange.webservices.data.core.enumeration.property.Importance;
import microsoft.exchange.webservices.data.core.request.HttpWebRequest;
import microsoft.exchange.webservices.data.core.service.item.EmailMessage;
import microsoft.exchange.webservices.data.credential.ExchangeCredentials;
import microsoft.exchange.webservices.data.misc.ImpersonatedUserId;
import microsoft.exchange.webservices.data.property.complex.EmailAddress;
import microsoft.exchange.webservices.data.property.complex.MessageBody;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Map;

public class TestExchangeAndOauth2 {

    public static void main(String[] args) throws Exception {
        String mailAddress = "邮箱账号";
        String tenant_id = "租户id";
        String client_id = "应用id";
        String client_secret = "密钥的值";//注意不是密钥的id
        String scope = "https://outlook.office365.com/.default";
        String url = "https://login.microsoftonline.com/" + tenant_id + "/oauth2/v2.0/token";
//        String scope = "https://partner.outlook.cn/.default";//中国版(21v世纪互联运营的)的微软邮箱账号需要设置这个地址
//        String url = "https://login.partner.microsoftonline.cn/" + tenant_id + "/oauth2/v2.0/token";//中国版(21v世纪互联运营的)的微软邮箱账号需要设置这个地址

        HttpClient httpClient = new HttpClient();
        PostMethod postMethod = new PostMethod(url);
        postMethod.addRequestHeader("accept", "*/*");
        postMethod.addRequestHeader("connection", "Keep-Alive");
        postMethod.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=GBK");

        //必须设置下面这个Header
        postMethod.addRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.81 Safari/537.36");
        //添加请求参数
        postMethod.addParameter("grant_type", "client_credentials");
        postMethod.addParameter("client_id", client_id);
        postMethod.addParameter("client_secret", client_secret);
        postMethod.addParameter("scope", scope);
        String token = "";

        try {
            int code = httpClient.executeMethod(postMethod);
            String resBody = postMethod.getResponseBodyAsString();
            if (code == 200) {
                Map<String, Object> map = JSON.parseObject(resBody, Map.class);
                token = (String) map.get("access_token");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            postMethod.releaseConnection();
        }

        ExchangeService service = new ExchangeService();

        service.setCredentials(new OAuth2Credentials(token));
        service.setTraceEnabled(true);
        service.traceMessage(TraceFlags.EwsRequest, "office365");
        service.setImpersonatedUserId(new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailAddress));
        service.setUrl(new URI("https://outlook.office365.com/ews/exchange.asmx"));
        //service.setUrl(new URI("https://partner.outlook.cn/ews/exchange.asmx"));//中国版(21v世纪互联运营的)的微软邮箱账号需要设置这个地址
        service.getHttpHeaders().put("X-AnchorMailbox", mailAddress);

        EmailMessage msg = new EmailMessage(service);
        msg.setFrom(new EmailAddress("mailAddress", mailAddress));
        msg.getToRecipients().add(new EmailAddress("收件人邮箱昵称", "收件人邮箱地址"));
        msg.setSubject("邮件oauth2测试");
        MessageBody messageBody = new MessageBody();
        messageBody.setBodyType(BodyType.Text);
        messageBody.setText("哈哈哈哈");
        msg.setBody(messageBody);

        msg.setImportance(Importance.Normal);
        msg.send();
    }

     static class OAuth2Credentials extends ExchangeCredentials {
         private String accessToken;

         public OAuth2Credentials(String accessToken) {
             Preconditions.checkNotNull(accessToken);
             this.accessToken = accessToken;
         }

         @Override
         public void prepareWebRequest(HttpWebRequest client)
                 throws URISyntaxException {
             super.prepareWebRequest(client);
             if (client.getHeaders() != null) client.getHeaders().put("Authorization", "Bearer " + accessToken);
         }
    }
}

这样就可以在oauth2认证方式下使用exchange协议进行发送邮件或者接收邮件了

### 使用 Java 调用 Microsoft Exchange 或 Outlook API 发送电子邮件 要在 Java 中调用 Microsoft Exchange 或 Outlook API 来发送电子邮件,可以采用两种主要方式:一是通过 EWS (Exchange Web Services) Managed API 实现;二是利用 Microsoft Graph API 完成。 #### 方法一:基于 EWS Managed API 的实现 EWS 是一种 SOAP 基础的服务接口,允许开发者访问 Exchange Server 功能。以下是具体步骤: 1. **引入依赖项** 需要下载并导入 EWS Managed API 库至项目中。可以通过 Maven 添加如下依赖: ```xml <dependency> <groupId>com.microsoft.exchange</groupId> <artifactId>microsoft-ews-java-api</artifactId> <version>2.0</version> </dependency> ``` 2. **编写代码逻辑** 下面是一个简单的例子展示如何使用 EWS 创建并发送邮件[^3]: ```java import microsoft.exchange.webservices.data.core.ExchangeService; import microsoft.exchange.webservices.data.core.enumeration.misc.ExchangeVersion; import microsoft.exchange.webservices.data.credential.WebCredentials; import microsoft.exchange.webservices.data.property.complex.EmailMessage; public class EmailSender { public static void main(String[] args) throws Exception { // 初始化服务实例 ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2); service.setUrl(new java.net.URI("https://outlook.office365.com/EWS/Exchange.asmx")); // 设置身份凭证(建议使用 OAuth2) service.setCredentials(new WebCredentials("username@domain.com", "password")); // 构建邮件对象 EmailMessage email = new EmailMessage(service); email.getToRecipients().add("recipient@example.com"); email.setSubject("Test Subject"); email.setBody("This is a test message."); // 发送邮件 email.send(); } } ``` 注意,在现代场景下推荐使用 OAuth2 认证替代基本用户名密码认证[^2]。 --- #### 方法二:基于 Microsoft Graph API 的实现 Microsoft Graph 提供了一个统一的 RESTful 接口来访问多个 Microsoft Cloud 服务的数据资源,包括但不限于 Outlook Mail、Calendar 和 Contacts 等。 1. **注册应用程序获取权限** 登录 Azure Portal 注册一个新的应用,并授予其必要的 API 权限(如 `Mail.Send`)。完成此操作后记录下 Application ID 和 Secret Key。 2. **安装库文件** 可以借助 MSAL Library 获取令牌以及简化请求过程。Maven POM 文件中的配置如下所示: ```xml <!-- MSAL Core --> <dependency> <groupId>com.microsoft.azure</groupId> <artifactId>msal4j</artifactId> <version>1.8.0</version> </dependency> <!-- HTTP Client --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.13</version> </dependency> ``` 3. **开发核心功能模块** 此处提供一段样例程序用于演示如何构建消息并通过 Graph Endpoint 投递出去[^4]: ```java import com.microsoft.aad.msal4j.*; import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import org.json.JSONObject; public class GraphEmailClient { private final String clientId = "<your_client_id>"; private final String tenantId = "<your_tenant_id>"; private final String clientSecret = "<your_secret_key>"; public static void sendEmail() throws Exception { PublicClientApplication app = PublicClientApplication.builder(clientId).build(); IAuthenticationResult result = acquireToken(app); JSONObject bodyJson = new JSONObject(); bodyJson.put("message", createMessage()); bodyJson.put("saveToSentItems", false); HttpClient httpClient = HttpClients.createDefault(); HttpPost postRequest = new HttpPost("https://graph.microsoft.com/v1.0/me/sendMail"); postRequest.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + result.accessToken()); postRequest.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); postRequest.setEntity(new StringEntity(bodyJson.toString())); HttpResponse response = httpClient.execute(postRequest); System.out.println(response.getStatusLine().getStatusCode()); } private static IAuthenticationResult acquireToken(PublicClientApplication pcaApp) throws MalformedURLException, InterruptedException, ExecutionException { Set<String> scopes = Collections.singleton("https://graph.microsoft.com/.default"); ConfidentialClientApplication ccaApp = ConfidentialClientApplication.builder( clientId, ClientCredentialFactory.createFromSecret(clientSecret)) .authority(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD + "/" + tenantId) .build(); ClientCredentialParameters parameters = ClientCredentialParameters.builder(scopes).build(); CompletableFuture<IAuthenticationResult> future = ccaApp.acquireToken(parameters); return future.get(); } private static JSONObject createMessage(){ InternetAddress toAddr = null; try {toAddr = new InternetAddress("receiver@example.com");} catch(AddressException e){e.printStackTrace();} JSONObject recipientObj = new JSONObject(); recipientObj.put("emailAddress",new JSONObject() .put("address","receiver@example.com") .put("name","Receiver Name")); JSONArray recipientsArr = new JSONArray(); recipientsArr.put(recipientObj); JSONObject mailMsg = new JSONObject(); mailMsg.put("subject","Testing from Java App"); mailMsg.put("body",new JSONObject() .put("contentType","HTML") .put("content","<h1>Hello!</h1><p>This is an automated test.</p>")); mailMsg.put("toRecipients",recipientsArr); return mailMsg; } } ``` 以上即为完整的解决方案说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

胖小八

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值