【问题标题】:JavaMail connecting to Office 365 XOAUTH2 for IMAP Authentication failsJavaMail 连接到 Office 365 XOAUTH2 以进行 IMAP 身份验证失败
【发布时间】:2020-10-24 04:01:06
【问题描述】:

面临使用 OAuth2.0 在线使用 Office365 的连接问题 我已经设置了应用程序权限以及 IMAP 和 SMTP 连接。基本身份验证似乎工作正常。我相信 IMAP 已启用。我的应用程序在任何组织目录(任何 Azure AD 目录 - 多租户)中配置为帐户,并使用授权类型授权代码。

并添加了委派的 Microsoft Graph 范围 https://graph.microsoft.com/IMAP.AccessAsUser.AllClient scopes added

请求的身份验证代码为https://login.microsoftonline.com/{tenantID}/oauth2/v2.0/authorize?response_type=code&client_id=1223&redirect_uri=http://localhost:5555 访问令牌请求https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token 请求的访问令牌,资源为“https://graph.microsoft.com”

Requesting Access token Image

成功接收到范围为 IMAP.AccessAsUser.All SMTP.Send 的访问令牌

{
    "token_type": "Bearer",
    "scope": "IMAP.AccessAsUser.All SMTP.Send",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "access_token",
    "refresh_token": "refresh_token",
    "id_token": "id_token"
} 

这里是Java代码(使用JavaMail jar 1.6.2)

Properties properties= new Properties();
properties.put("mail.imap.ssl.enable", "true");
properties.put("mail.imap.auth.mechanisms", "XOAUTH2");
//properties.put("mail.imap.sasl.enable", "true"); un-commented still results are same
properties.put("mail.imap.auth.login.disable", "true");
properties.put("mail.imap.auth.plain.disable", "true");
properties.put("mail.debug", "true");
properties.put("mail.debug.auth", "true");

Session session = Session.getInstance(props);
session.setDebug(true);

String userEmail = "emailuser@domain.onmicrosoft.com";
String accessToken = "accessToken";

final Store store = session.getStore("imap");
store.connect("outlook.office365.com","993",userEmail, accessToken);

以下输出:

DEBUG: JavaMail version 1.6.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: getProvider() returning javax.mail.Provider[STORE,imap,com.sun.mail.imap.IMAPStore,Oracle]
DEBUG IMAP: mail.imap.appendbuffersize: -1
DEBUG IMAP: mail.imap.minidletime: 10
DEBUG IMAP: closeFoldersOnStoreFailure
DEBUG IMAP: trying to connect to host "outlook.office365.com", port 993, isSSL true
* OK The Microsoft Exchange IMAP4 service is ready. [TQBB]
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS 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, user=emailuser@domain.onmicrosoft.com, 
password=<non-null>
A1 AUTHENTICATE XOAUTH2 dXNlAQE=
A1 NO AUTHENTICATE failed.
Could not connect to the message store
javax.mail.AuthenticationFailedException: AUTHENTICATE failed.
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:731)
at javax.mail.Service.connect(Service.java:366)
at myproject.EmailReceiver.downloadEmails(EmailReceiver.java:79)
at myproject.EmailReceiver.main(EmailReceiver.java:179)

以下其他帖子无法在我的 Azure 中找到范围 https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/SMTP.Send。可能它们是旧范围。

除了“https://graph.microsoft.com/IMAP.AccessAsUser.All”和“https://graph.microsoft.com/SMTP.send”之外,是否还有其他范围需要通过在线连接到 Exchange地图。或者现有代码有任何问题。

问题已解决,我使用作用域 offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send 它提供访问邮件的权限,还提供刷新令牌以重新生成访问令牌。

注意: 将范围更改为 offline_access https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/SMTP.Send 解决了问题。

【问题讨论】:

  • 您是否编辑了A1 AUTHENTICATE XOAUTH2 dXNlAQE= 中的一些base64?这丢失了很多登录信息(这可能是库的安全功能)。它解码为“use\x01\x01”,它不是有效的 XOAUTH2 字符串。另外:您是否在一小时内使用了您的访问令牌?
  • 嗨 Max,由于“A1 AUTHENTICATE XOAUTH2 dXNlAQE=" 是安全信息,我删除了剩余的字符串。另外:您是否在一小时内使用了访问令牌?是的,我在一小时内使用访问令牌。
  • 在 JavaMail 库中进行编码 " String resp = "user=" + u + "\001auth=Bearer " + p + "\001\001"; byte[] ba = BASE64EncoderStream.encode( resp.getBytes(StandardCharsets.UTF_8)); "
  • 好的,只是想确保您已编辑它并且您没有以某种方式破坏库;)。 MS 的 OAUTH2 是相当新的,所以没有太多关于它如何或为什么会中断的集体知识,而且他们似乎没有提供非常有用的错误消息。 :(

标签: azure oauth-2.0 office365 jakarta-mail imap


【解决方案1】:

我认为您的问题与访问令牌范围有关。我正在开发一个类似的应用程序,但我正在使用范围 https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/SMTP.Send 来获取访问令牌,如果我尝试使用 SMTP.Send 和 IMAP.AccessAsUserAll,它似乎不起作用。

我的访问令牌如下所示: {"token_type":"承载者", “范围”:“https://outlook.office365.com/IMAP.AccessAsUser.Allhttps://outlook.office365.com/SMTP.Send", “expires_in”:3599, “ext_expires_in”:3599, "access_token":"eyJ0eXAiOi..."}

在 azure 应用配置中,我只有 IMAP 和 SMTP 的 Microsoft Graph 权限。

【讨论】:

  • 非常感谢您的回答。即使我认为问题取决于我正在使用的访问令牌范围。但不幸的是,由于某种原因,我无法在我的应用程序中添加范围 outlook.office365.com/IMAP.AccessAsUser.All outlook.office365.com/SMTP.Send。我与支持团队进行了沟通,他们告诉我这些是遗留范围并且已被删除。那么你现在有没有机会添加这些范围?您现在可以在 Exchange 中看到它们吗?我问这个问题只是为了确保在添加这些范围时我可能会遇到一些权限问题。
  • 我不确定您添加范围的意思。我对注册应用程序的唯一权限是屏幕截图中的权限,它的工作原理是这样的。这个项目帮了我很多github.com/eino-makitalo/vesa-mailtest.
  • 我不知道outlook.office365.com/IMAP.AccessAsUser.All 和 IMAP.AccessUserAsAll 之间有什么区别...我认为它们毕竟是一回事...我尝试从应用注册,如果我尝试使用outlook.office365.com/IMAP.AccessAsUser.All 范围请求访问令牌,它将不再给我令牌,所以这是与此范围相对应的权限。
  • 如果您在获取访问令牌的同时发布您正在发出的请求,这将非常有帮助。 { “token_type”:“Bearer”,“范围”:“IMAP.AccessAsUser.All SMTP.Send”,“expires_in”:3599,“ext_expires_in”:3599,“access_token”:“access_token”,“refresh_token”:“refresh_token” ", "id_token": "id_token" } 但你有 "scope":"outlook.office365.com/IMAP.AccessAsUser.All" 我试图了解这里可能有什么问题。我将附加我正在发出的(AccessTokenRequest)请求。如果我在这里做错了,请告诉我
  • 我添加了在获取身份验证代码和访问令牌“请求访问令牌图像”时发出的请求。请看一下。
猜你喜欢
  • 2020-08-19
  • 2020-11-10
  • 2016-05-20
  • 1970-01-01
  • 2021-10-13
  • 2015-06-27
  • 1970-01-01
  • 2016-01-26
  • 2011-05-19
相关资源
最近更新 更多