由于 Microsoft 宣布很快将无法再通过基本身份验证访问 Outlook IMAP 邮箱,因此我正在尝试弄清楚如何在 Java 中使用 OAUTH2 正确打开 IMAP 邮箱。但我总是收到错误代码“A1 NO AUTHENTICATE failed”。
我正在做的事情如下:
我有一种生成 OAUTH2 访问令牌的方法:
public String getAuthToken(String tanantId,String clientId,String client_secret) throws ClientProtocolException, IOException {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost loginPost = new HttpPost("https://login.microsoftonline.com/" + tanantId + "/oauth2/v2.0/token");
String scopes = "https://outlook.office365.com/.default";
String encodedBody = "client_id=" + clientId + "&scope=" + scopes + "&client_secret=" + client_secret
+ "&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();
byte[] response = readAllBytes(inputStream);
ObjectMapper objectMapper = new ObjectMapper();
JavaType type = objectMapper.constructType(
objectMapper.getTypeFactory().constructParametricType(Map.class, String.class, String.class));
Map<String, String> parsed = new ObjectMapper().readValue(response, type);
return parsed.get("access_token");
}
生成的令牌似乎有效jwt.ms https://jwt.ms允许我解码令牌。
我尝试使用访问令牌通过 XOAUTH2 访问邮箱,如下所示:
Properties props = new Properties();
props.put("mail.store.protocol", "imap");
props.put("mail.imap.host", "outlook.office365.com");
props.put("mail.imap.port", "993");
props.put("mail.imap.ssl.enable", "true");
props.put("mail.imap.starttls.enable", "true");
props.put("mail.imap.auth", "true");
props.put("mail.imap.auth.mechanisms", "XOAUTH2");
props.put("mail.imap.user", mailAddress);
props.put("mail.debug", "true");
props.put("mail.debug.auth", "true");
// open mailbox....
String token = getAuthToken(tanantId,clientId,client_secret);
Session session = Session.getInstance(props);
session.setDebug(true);
Store store = session.getStore("imap");
store.connect("outlook.office365.com", mailAddress, token);
但结果总是一个AuthenticationFailedException
:
* OK The Microsoft Exchange IMAP4 service is ready. [...............AA==]
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG IMAP: AUTH: PLAIN
DEBUG IMAP: AUTH: XOAUTH2
DEBUG IMAP: protocolConnect login, host=outlook.office365.com, [email protected] /cdn-cgi/l/email-protection, password=<non-null>
A1 AUTHENTICATE XOAUTH2 ....E=
A1 NO AUTHENTICATE failed.
javax.mail.AuthenticationFailedException: AUTHENTICATE failed.
From 这个类似的问题 https://stackoverflow.com/questions/73463357/cannot-authenticate-to-imap-on-office365-using-javamail我现在怀疑我的访问令牌实际上访问邮箱的权限太少。
我该如何澄清这一点?例如,当我解码令牌时,我可以看到它不包含scp
or roles
属性。
这是否表明令牌错误?