Office 365 XOAUTH2用于IMAP和SMTP身份验证失败。

huangapple go评论82阅读模式
英文:

Office 365 XOAUTH2 for IMAP and SMTP Authentication fails

问题

最近在 Exchange Online 中支持 IMAP 和 SMTP 的 OAuth 2.0 已经宣布。

按照 指南,我已经设置了应用程序权限以及 IMAP 和 SMTP 连接。该应用程序配置为“任何组织目录中的帐户(任何 Azure AD 目录 - 多租户)”,并使用了 授权代码流程

以下 URL 用于授权:

并且已添加了以下委派的 Microsoft Graph 范围:

Office 365 XOAUTH2用于IMAP和SMTP身份验证失败。

这些范围,来自代码请求:

final List<String> scopes = Arrays.asList(
    "offline_access",
    "email",
    "openid",
    "profile",
    "User.Read",
    "Mail.ReadWrite",
    "https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All",
    "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send"
);

我成功地收到了访问令牌和刷新令牌:

{
    "token_type": "Bearer",
    "scope": "email IMAP.AccessAsUser.All Mail.ReadWrite openid profile SMTP.Send User.Read",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "编辑后的访问令牌",
    "refresh_token": "编辑后的刷新令牌",
    "id_token": "编辑后的身份令牌"
}

以下是用于连接到 IMAP 的代码:

Properties props = new Properties();
props.put("mail.imap.ssl.enable", "true");
props.put("mail.imaps.sasl.enable", "true");
props.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
props.put("mail.imap.auth.login.disable", "true");
props.put("mail.imap.auth.plain.disable", "true");
props.put("mail.debug", "true");
props.put("mail.debug.auth", "true");

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

String userEmail = "user@domain.onmicrosoft.com";
String accessToken = "在前一步中获得的访问令牌";

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

这会生成以下输出:

DEBUG: JavaMail 版本 1.6.2
DEBUG: 成功加载资源:/META-INF/javamail.default.address.map
DEBUG: setDebug:JavaMail 版本 1.6.2
DEBUG: getProvider() 返回 javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle]
DEBUG IMAPS: mail.imap.fetchsize: 16384
DEBUG IMAPS: mail.imap.ignorebodystructuresize: false
DEBUG IMAPS: mail.imap.statuscachetimeout: 1000
DEBUG IMAPS: mail.imap.appendbuffersize: -1
DEBUG IMAPS: mail.imap.minidletime: 10
DEBUG IMAPS: 启用 SASL
DEBUG IMAPS: 允许的 SASL 机制:XOAUTH2
DEBUG IMAPS: closeFoldersOnStoreFailure
DEBUG IMAPS: 正在尝试连接到主机“outlook.office365.com”,端口 993,isSSL 为 true
* OK The Microsoft Exchange IMAP4 service is ready. [QQBNADc...]
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG IMAPS: AUTH: PLAIN
DEBUG IMAPS: AUTH: XOAUTH2
DEBUG IMAPS: protocolConnect login,host=outlook.office365.com,user=user@domain.onmicrosoft.com,password=<non-null>
DEBUG IMAPS: SASL 机制:
DEBUG IMAPS:  XOAUTH2
DEBUG IMAPS: 
DEBUG IMAPS: SASL 客户端 XOAUTH2
DEBUG IMAPS: SASL 回调长度:2
DEBUG IMAPS: SASL 回调 0:javax.security.auth.callback.NameCallback@17046283
DEBUG IMAPS: SASL 回调 1:javax.security.auth.callback.PasswordCallback@5bd03f44
A1 AUTHENTICATE XOAUTH2 dXNlcj1o...
A1 NO AUTHENTICATE failed.

Exception in thread "main" javax.mail.AuthenticationFailedException: AUTHENTICATE failed.
	at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:732)
	at javax.mail.Service.connect(Service.java:366)

用于连接到 SMTP 的代码如下:

Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
props.put("mail.smtp.auth.login.disable", "true");
props.put("mail.smtp.auth.plain.disable", "true");
props.put("mail.debug.auth", "true");

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

String userEmail = "user@domain.onmicrosoft.com";
String accessToken = "在前一步中获得的访问令牌";

Transport transport = session.getTransport("smtp");
transport.connect("smtp.office365.com", 587, userEmail, accessToken);

这将提供以下输出:

DEBUG: setDebug:JavaMail 版本 1.6.2
DEBUG: getProvider() 返回 javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true,useAuth true
DEBUG SMTP: 正在尝试连接到主机“smtp.office365.com”,端口 587,isSSL 为 false
220 AM5PR0701CA0005.outlook.office365.com Microsoft ESMTP MAIL Service ready at Mon, 4 May 2020 15:52:28 +0000
DEBUG SMTP: 连接到主机“smtp.office365.com”,端口:587
EHLO ubuntu-B450-AORUS-M
250-AM5PR0701CA0005.outlook.office365.com Hello [my ip here]
250-SIZE 157286400
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: 找到

<details>
<summary>英文:</summary>

Recently the [support for OAuth 2.0 for IMAP and SMTP in the Exchange Online][1] has been announced.
Following [the guide][2] I&#39;ve set up the application permissions and IMAP and SMTP connection.
The application is configured as `Accounts in any organizational directory (Any Azure AD directory - Multitenant)` and uses [authorization code flow][3].

URLs below are used for authorization:

- https://login.microsoftonline.com/organizations/oauth2/v2.0/authorize
- https://login.microsoftonline.com/organizations/oauth2/v2.0/token

And the following Delegated Microsoft Graph scopes have been added:

[![enter image description here][4]][4]

The scopes, requests from code:

```java
final List&lt;String&gt; scopes = Arrays.asList(
    &quot;offline_access&quot;,
    &quot;email&quot;,
    &quot;openid&quot;,
    &quot;profile&quot;,
    &quot;User.Read&quot;,
    &quot;Mail.ReadWrite&quot;,
    &quot;https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All&quot;,
    &quot;https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&quot;
);

I successfully receive the access and refresh tokens:

{
    &quot;token_type&quot;: &quot;Bearer&quot;,
    &quot;scope&quot;: &quot;email IMAP.AccessAsUser.All Mail.ReadWrite openid profile SMTP.Send User.Read&quot;,
    &quot;expires_in&quot;: 3599,
    &quot;ext_expires_in&quot;: 3599,
    &quot;access_token&quot;: &quot;edited&quot;,
    &quot;refresh_token&quot;: &quot;edited&quot;,
    &quot;id_token&quot;: &quot;edited&quot;
}

Here's the code, used to connect to IMAP:

Properties props = new Properties();
props.put(&quot;mail.imap.ssl.enable&quot;, &quot;true&quot;);
props.put(&quot;mail.imaps.sasl.enable&quot;, &quot;true&quot;);
props.put(&quot;mail.imaps.sasl.mechanisms&quot;, &quot;XOAUTH2&quot;);
props.put(&quot;mail.imap.auth.login.disable&quot;, &quot;true&quot;);
props.put(&quot;mail.imap.auth.plain.disable&quot;, &quot;true&quot;);
props.put(&quot;mail.debug&quot;, &quot;true&quot;);
props.put(&quot;mail.debug.auth&quot;, &quot;true&quot;);

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

String userEmail = &quot;user@domain.onmicrosoft.com&quot;;
String accessToken = &quot;access_token_received_on_previous_step&quot;;

final Store store = session.getStore(&quot;imaps&quot;);
store.connect(&quot;outlook.office365.com&quot;, 993, userEmail, accessToken);

Which generates the following output:

DEBUG: JavaMail version 1.6.2
DEBUG: successfully loaded resource: /META-INF/javamail.default.address.map
DEBUG: setDebug: JavaMail version 1.6.2
DEBUG: getProvider() returning javax.mail.Provider[STORE,imaps,com.sun.mail.imap.IMAPSSLStore,Oracle]
DEBUG IMAPS: mail.imap.fetchsize: 16384
DEBUG IMAPS: mail.imap.ignorebodystructuresize: false
DEBUG IMAPS: mail.imap.statuscachetimeout: 1000
DEBUG IMAPS: mail.imap.appendbuffersize: -1
DEBUG IMAPS: mail.imap.minidletime: 10
DEBUG IMAPS: enable SASL
DEBUG IMAPS: SASL mechanisms allowed: XOAUTH2
DEBUG IMAPS: closeFoldersOnStoreFailure
DEBUG IMAPS: trying to connect to host &quot;outlook.office365.com&quot;, port 993, isSSL true
* OK The Microsoft Exchange IMAP4 service is ready. [QQBNADc...]
A0 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
A0 OK CAPABILITY completed.
DEBUG IMAPS: AUTH: PLAIN
DEBUG IMAPS: AUTH: XOAUTH2
DEBUG IMAPS: protocolConnect login, host=outlook.office365.com, user=user@domain.onmicrosoft.com, password=&lt;non-null&gt;
DEBUG IMAPS: SASL Mechanisms:
DEBUG IMAPS:  XOAUTH2
DEBUG IMAPS: 
DEBUG IMAPS: SASL client XOAUTH2
DEBUG IMAPS: SASL callback length: 2
DEBUG IMAPS: SASL callback 0: javax.security.auth.callback.NameCallback@17046283
DEBUG IMAPS: SASL callback 1: javax.security.auth.callback.PasswordCallback@5bd03f44
A1 AUTHENTICATE XOAUTH2 dXNlcj1o...
A1 NO AUTHENTICATE failed.

Exception in thread &quot;main&quot; javax.mail.AuthenticationFailedException: AUTHENTICATE failed.
	at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:732)
	at javax.mail.Service.connect(Service.java:366)

And the following code is used for connecting to SMTP:

Properties props = new Properties();
props.put(&quot;mail.smtp.auth&quot;, &quot;true&quot;);
props.put(&quot;mail.transport.protocol&quot;, &quot;smtp&quot;);
props.put(&quot;mail.smtp.starttls.enable&quot;, &quot;true&quot;);
props.put(&quot;mail.smtp.auth.mechanisms&quot;, &quot;XOAUTH2&quot;);
props.put(&quot;mail.smtp.auth.login.disable&quot;,&quot;true&quot;);
props.put(&quot;mail.smtp.auth.plain.disable&quot;,&quot;true&quot;);
props.put(&quot;mail.debug.auth&quot;, &quot;true&quot;);

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

String userEmail = &quot;user@domain.onmicrosoft.com&quot;;
String accessToken = &quot;access_token_received_on_previous_step&quot;;

Transport transport = session.getTransport(&quot;smtp&quot;);
transport.connect(&quot;smtp.office365.com&quot;, 587, userEmail, accessToken);

Which provides the output below:

DEBUG: setDebug: JavaMail version 1.6.2
DEBUG: getProvider() returning javax.mail.Provider[TRANSPORT,smtp,com.sun.mail.smtp.SMTPTransport,Oracle]
DEBUG SMTP: useEhlo true, useAuth true
DEBUG SMTP: trying to connect to host &quot;smtp.office365.com&quot;, port 587, isSSL false
220 AM5PR0701CA0005.outlook.office365.com Microsoft ESMTP MAIL Service ready at Mon, 4 May 2020 15:52:28 +0000
DEBUG SMTP: connected to host &quot;smtp.office365.com&quot;, port: 587
EHLO ubuntu-B450-AORUS-M
250-AM5PR0701CA0005.outlook.office365.com Hello [my ip here]
250-SIZE 157286400
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-STARTTLS
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension &quot;SIZE&quot;, arg &quot;157286400&quot;
DEBUG SMTP: Found extension &quot;PIPELINING&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;DSN&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;ENHANCEDSTATUSCODES&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;STARTTLS&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;8BITMIME&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;BINARYMIME&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;CHUNKING&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;SMTPUTF8&quot;, arg &quot;&quot;
STARTTLS
220 2.0.0 SMTP server ready
EHLO ubuntu-B450-AORUS-M
250-AM5PR0701CA0005.outlook.office365.com Hello [my ip here]
250-SIZE 157286400
250-PIPELINING
250-DSN
250-ENHANCEDSTATUSCODES
250-AUTH LOGIN XOAUTH2
250-8BITMIME
250-BINARYMIME
250-CHUNKING
250 SMTPUTF8
DEBUG SMTP: Found extension &quot;SIZE&quot;, arg &quot;157286400&quot;
DEBUG SMTP: Found extension &quot;PIPELINING&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;DSN&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;ENHANCEDSTATUSCODES&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;AUTH&quot;, arg &quot;LOGIN XOAUTH2&quot;
DEBUG SMTP: Found extension &quot;8BITMIME&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;BINARYMIME&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;CHUNKING&quot;, arg &quot;&quot;
DEBUG SMTP: Found extension &quot;SMTPUTF8&quot;, arg &quot;&quot;
DEBUG SMTP: protocolConnect login, host=smtp.office365.com, user=user@domain.onmicrosoft.com, password=&lt;non-null&gt;
DEBUG SMTP: Attempt to authenticate using mechanisms: XOAUTH2
DEBUG SMTP: Using mechanism XOAUTH2
AUTH XOAUTH2 dXNlcj1obW9kaUB...
535 5.7.3 Authentication unsuccessful [AM5PR0701CA0005.eurprd07.prod.outlook.com]

Exception in thread &quot;main&quot; javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful [AM5PR0701CA0005.eurprd07.prod.outlook.com]
	at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:965)
	at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:876)
	at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:780)
	at javax.mail.Service.connect(Service.java:366)

What I've also tried:

  • specifying scopes as https://graph.microsoft.com/SMTP.Send and just SMTP.Send
  • using https://login.microsoftonline.com/common/ url for authentication

Result is always the same.

Is it something I do wrong or there's a bug somewhere in the support for this from the Microsoft side?

Update 1:

Tried from the command line, but same result:

$ openssl s_client -crlf -connect outlook.office365.com:993
... connection part omitted
* OK The Microsoft Exchange IMAP4 service is ready. [QQBNADYAUAAxADkAMgBDAEEAMAAwADkAMQAuAEUAVQBSAFAAMQA5ADIALgBQAFIATwBEAC4ATwBVAFQATABPAE8ASwAuAEMATwBNAA==]
C01 CAPABILITY
* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS ID UNSELECT CHILDREN IDLE NAMESPACE LITERAL+
C01 OK CAPABILITY completed.
A01 AUTHENTICATE XOAUTH2 dXNlcj1obW9kaUBjb...
A01 NO AUTHENTICATE failed.
* BYE Connection is closed. 13
read:errno=0

Update 2:

Tried to create brand new application in the Azure Portal with the following permissions:

Office 365 XOAUTH2用于IMAP和SMTP身份验证失败。

And receiving the following screen, when trying to give consent for scopes:

Office 365 XOAUTH2用于IMAP和SMTP身份验证失败。

That is odd, because the permissions from Azure Portal don't specify that the Admin consent is required and my previous app registration doesn't show such screen when IMAP and SMTP scopes are requested.

Update 3:

Thanks to comments to this post I tried the following scopes:

public static final List&lt;String&gt; SCOPES = Arrays.asList(
    &quot;offline_access&quot;,
    &quot;https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All&quot;,
    &quot;https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&quot;
);

Which gave me the token below:

{
    &quot;token_type&quot;: &quot;Bearer&quot;,
    &quot;scope&quot;: &quot;https://outlook.office365.com/IMAP.AccessAsUser.All https://outlook.office365.com/SMTP.Send&quot;,
    &quot;expires_in&quot;: 3599,
    &quot;ext_expires_in&quot;: 3599,
    &quot;access_token&quot;: &quot;eyJ0eXAiOiJKV1....&quot;,
    &quot;refresh_token&quot;: &quot;OAQABAAAAAAAm....&quot;
}

IMAP/SMTP auth was successful and I was able to read the inbox + send an email!

But for my application I need also couple of other scopes to use some MS Graph API endpoints (read user profile, messages subscription and messages deletion).

So I tried different scopes:

public static final List&lt;String&gt; SCOPES = Arrays.asList(
        &quot;offline_access&quot;,
        &quot;User.Read&quot;,
        &quot;Mail.ReadWrite&quot;,
        &quot;https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All&quot;,
        &quot;https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&quot;
);

This gave the token (note that scope value differs from the token that actually worked, the permissions don't have outlook url):

{
    &quot;token_type&quot;: &quot;Bearer&quot;,
    &quot;scope&quot;: &quot;IMAP.AccessAsUser.All Mail.ReadWrite SMTP.Send User.Read profile openid email&quot;,
    &quot;expires_in&quot;: 3599,
    &quot;ext_expires_in&quot;: 3599,
    &quot;access_token&quot;: &quot;eyJ0eXAiOiJKV1Q...&quot;,
    &quot;refresh_token&quot;: &quot;OAQABAAAAAAAm...&quot;
}

Which led to the result I got previously:

A1 NO AUTHENTICATE failed.

Trying all the scopes to be as URLs:

public static final List&lt;String&gt; SCOPES = Arrays.asList(
        &quot;offline_access&quot;, // or &quot;https%3A%2F%2Fgraph.microsoft.com%2Foffline_access&quot;
        &quot;https%3A%2F%2Fgraph.microsoft.com%2FUser.Read&quot;,
        &quot;https%3A%2F%2Fgraph.microsoft.com%2FMail.ReadWrite&quot;,
        &quot;https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All&quot;,
        &quot;https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&quot;
);

Leads to the following error when obtaining the token (the consent step passed successfully):

{
    &quot;error&quot;: &quot;invalid_request&quot;,
    &quot;error_description&quot;: &quot;AADSTS28000: Provided value for the input parameter scope is not valid because it contains more than one resource. Scope offline_access https://graph.microsoft.com/user.read https://graph.microsoft.com/mail.readwrite https://outlook.office365.com/imap.accessasuser.all https://outlook.office365.com/smtp.send is not valid.\r\nTrace ID: c3282396-6231-4e11-8300-77bc2ca57f00\r\nCorrelation ID: 5f5145bf-7114-4e6c-ab11-30e7ff84a056\r\nTimestamp: 2020-05-06 08:08:48Z&quot;,
    &quot;error_codes&quot;: [
        28000
    ],
    &quot;timestamp&quot;: &quot;2020-05-06 08:08:48Z&quot;,
    &quot;trace_id&quot;: &quot;c3282396-6231-4e11-8300-77bc2ca57f00&quot;,
    &quot;correlation_id&quot;: &quot;5f5145bf-7114-4e6c-ab11-30e7ff84a056&quot;
}

And when trying all the scopes to have microsoft graph (as copied from the Azure Portal)

public static final List&lt;String&gt; SCOPES = Arrays.asList(
    &quot;https%3A%2F%2Fgraph.microsoft.com%2Foffline_access&quot;,
    &quot;https%3A%2F%2Fgraph.microsoft.com%2FUser.Read&quot;,
    &quot;https%3A%2F%2Fgraph.microsoft.com%2FMail.ReadWrite&quot;,
    &quot;https%3A%2F%2Fgraph.microsoft.com%2FIMAP.AccessAsUser.All&quot;,
    &quot;https%3A%2F%2Fgraph.microsoft.com%2FSMTP.Send&quot;
);

Return the following token (without a refresh token althout offline_access has been requested)

{
    &quot;token_type&quot;: &quot;Bearer&quot;,
    &quot;scope&quot;: &quot;profile openid email https://graph.microsoft.com/IMAP.AccessAsUser.All https://graph.microsoft.com/Mail.ReadWrite https://graph.microsoft.com/SMTP.Send https://graph.microsoft.com/User.Read&quot;,
    &quot;expires_in&quot;: 3599,
    &quot;ext_expires_in&quot;: 3599,
    &quot;access_token&quot;: &quot;eyJ0eXAiOiJKV1...&quot;
}

No success:

A1 NO AUTHENTICATE failed.

So it appears that if you don't specify Outlook url for scope it's assumed probably as Graph one which doesn't allow authorization through IMAP and SMTP.

Update 4:

By requesting all the scopes I need at consent step, then getting first access token with only Graph scopes and the second one using refresh token endpoint specifying Outlook scopes - it worked.
Refresh token method for getting second access token is used because if you try to obtains access token by auth code you'll get get the following error:

{
    &quot;error&quot;: &quot;invalid_grant&quot;,
    &quot;error_description&quot;: &quot;AADSTS54005: OAuth2 Authorization code was already redeemed, please retry with a new valid code or use an existing refresh token.\r\nTrace ID: 09fc80f4-f5fd-4e52-938f-d56b71dd0900\r\nCorrelation ID: 4f35e05c-23c8-4fdc-a5a7-2fcde5a73b44\r\nTimestamp: 2020-05-08 12:13:30Z&quot;,
    &quot;error_codes&quot;: [
        54005
    ],
    &quot;timestamp&quot;: &quot;2020-05-08 12:13:30Z&quot;,
    &quot;trace_id&quot;: &quot;09fc80f4-f5fd-4e52-938f-d56b71dd0900&quot;,
    &quot;correlation_id&quot;: &quot;4f35e05c-23c8-4fdc-a5a7-2fcde5a73b44&quot;
}

So no I'll need to use two separate tokens depending on what resource I'll need to manage.

Update 5:

If it still doesn't work - check if your organization has Security Default enabled - they disable POP/IMAP/SMTP auth for accounts - https://techcommunity.microsoft.com/t5/exchange-team-blog/announcing-oauth-2-0-support-for-imap-and-smtp-auth-protocols-in/bc-p/1544725/highlight/true#M28589

答案1

得分: 9

IMAP和SMTP范围针对的是Exchange资源,而不是Graph资源。而User.Read和Mail.ReadWrite则针对Graph资源。

我们不支持生成同时针对两个资源的令牌。因此出现错误:“提供的输入参数范围的值无效,因为它包含多个资源。”

您应该通过两次对/token的调用分别生成两个令牌。

  1. 一个令牌包含为Exchange资源生成的IMAP和SMTP范围。
  2. 另一个令牌包含针对Graph资源的Graph范围(User.Read、Mail.ReadWrite)。
英文:

IMAP, SMTP scopes are targeted for Exchange resource and not Graph. Whereas User.Read, Mail.ReadWrite are meant for Graph resource.

We do not support generation of tokens that are meant for two resources. Hence the error "Provided value for the input parameter scope is not valid because it contains more than one resource."

You should generate two tokens separately by two calls to /token.

  1. One with the IMAP, SMTP scopes generated for the Exchange resource.
  2. The other with Graph scopes (User.Read, Mail.ReadWrite) meant for Graph resource.

答案2

得分: 4

其他的回答已经指出:虽然你可以在 /authorize 端点同时授权不相关的范围,但每次调用 /token 端点可能仅涉及一组相关的范围。

问题和几个回答还提出了以下问题:IMAP/POP/SMTP 的范围是否应该以 https://graph.microsoft.com/ 还是 https://outlook.office365.com/ 为前缀?实际上,Microsoft 文档 指出,范围名称应该以 https://outlook.office.com/ 为前缀:

<!-- language: lang-none -->

协议      权限范围字符串
--------  -----------------------
IMAP      https://outlook.office.com/IMAP.AccessAsUser.All
POP       https://outlook.office.com/POP.AccessAsUser.All
SMTP      https://outlook.office.com/SMTP.Send
英文:

Other responses already point out: although you can simultaneously authorize unrelated scopes at the /authorize endpoint, each call to the /token endpoint may involve only a subset of related scopes.

The question and several responses also raise the following issue: Should the scopes for IMAP/POP/SMTP be prefixed with https://graph.microsoft.com/ or https://outlook.office365.com/ or what? In fact, Microsoft documents that the scope names should be prefixed with https://outlook.office.com/:

<!-- language: lang-none -->

Protocol  Permission scope string
--------  -----------------------
IMAP      https://outlook.office.com/IMAP.AccessAsUser.All
POP       https://outlook.office.com/POP.AccessAsUser.All
SMTP      https://outlook.office.com/SMTP.Send

答案3

得分: 1

@ldniov,我没有找到与我所做的任何不同之处。
以下是我使用的命令,仅供参考。

    /* 用户将被重定向以提供同意的网址 */
    https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
    client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03
    &amp;response_type=code
    &amp;redirect_uri=https%3A%2F%2Fimap2.mailboxsync.com%2Fredirect%2F
    &amp;response_mode=query
    &amp;scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send
    &amp;state=12345

    /* 用户提供同意后,将授权代码交换为刷新和访问令牌 */
    curl -XPOST https://login.microsoftonline.com/test.onmicrosoft.com/oauth2/v2.0/token -d &quot;client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03&amp;scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&amp;code=OAQABAAIAAAAm-06blBE1TpVMil8KPQ41HA4-ey0WVgK6WhqDDWBLoHBXdigqd8S_gE-uJBqH8f3z5U61GGQ_c_uJ__1n2r_IqwzTwjkmrd_VumomR-DaTz6tk0YUD6MdD5wZFC6ZET9N6clCnjSPnsBJ0Ee95qrLywipGqp9NL3Puea8AWZr06ltVrruvMpS9JOawOMgBMtbuUQjT_-C8EFmCz7yS-Iv-VjJYwlZ0S5jKnmRv9Iku8xt42VNjNsrRUVUJpvjbvRJWrmX6GYCD82VlQPntlwcTABqTsn-oNlFmFtbuE9fggTdvmRjq4diEPlwFHp0Fhjzolsmodh8tSIj0z2jHZXWFw3nbetaz_n71NSVc2DfKsKlr4sl-Zyew2xexOOwoHIkI33HVI3Hl0W-93zRkWMh5QxyDnU1R8pLVCU0GF1COThUvj1qaTpUW26nOgWdG1q0hXbLyhHe0HaLCY-RA0yg2fe49jCHNhOFiimkOgLrLD1a_-ICLhlAYkRUbd-aXdpbYZNOphvhNDkMqNILwk9LOHW3Cbsk6YDi1bwBTB2XTOvjyzb4uLz0_1exGc0XyA7wrSHf5l97k66sHgN6gEBKq-fgAOIgPMKPpovZ1ZiplS8Cd7ifcFmPfnAL5_ZJbt_0SCltNTX8v_qJRedCk8lNIoz18104eOdOyPyjFixlVi0MVpSFBoR6gEydFqoAeiwgAA&amp;state=12345&amp;session_state=1fab1545-2dc5-4102-b145-6258ea1ce97e&amp;state=12345&amp;redirect_uri=https%3A%2F%2Fimap2.mailboxsync.com%2Fredirect%2F&amp;client_secret=xxxx&amp;grant_type=authorization_code&quot;

    /* 将刷新令牌交换为新的访问令牌 */
    curl -XPOST https://login.microsoftonline.com/test.onmicrosoft.com/oauth2/v2.0/token -d &quot;client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03&amp;scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&amp;refresh_token=OAQABAAAAAAAm-06blBE1TpVMil8KPQ41c8A8SyRZDLkMDX7Vm5ay9zjRE7DfM5Mwo26ooW2zeB6pgKGZr1KPKko7XMSHM8DJj71i8TnCOrg4doYCsuGKGCw5fC74KKtp2wLD7w1mJ4BQJqldj2-42VqN63x8U9wGibI_DqBTn2VxGxaHbtpIGtNwzR4xwQgDt9-BiotNIuYksxmF9ZCIr6X_uMLvI4DLsBXxe67YsSlvR9VrU8cH-xJddMGPaDyJisWDcR0uW0-yk0b24zYaj4G203ksEji5wiPbuT_PeBrjV5b638s26AX_nMfvXSAjJfq-jWHouynq-3VYZp63eJ2o36yQWDUUMAXZ6-OT2Kl9-n4Y2kVkGNdepp_RBBQ7BDceip7J2nf5tHQKDm4S3nPGkfUNIyzk3I5jurLm9tyK8bVHzSEMz8TSg5slj_6Vsk0Oa1BWwW4tgdwWjsUm344jTMpfhc9iGDbc98o_47v7BfnUYZCtWLFQQxd68i01JPZvcyEp4T8aE42rQVtR55DqN3_7NYfPQBzdK_qX1Ue4r7ptOs7BIrRQgvSvuTE--ATVYwqD6s_XEeBZnnX8x1_2-o0VOmnTP8_2FvhvhgCj93F7VK0yZ

<details>
<summary>英文:</summary>

@ldniov, I couldn&#39;t find anything different from what I have done.
Providing commands I used below for reference.

    /* Url where users would be redirected to give consent */
    https://login.microsoftonline.com/common/oauth2/v2.0/authorize?
    client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03
    &amp;response_type=code
    &amp;redirect_uri=https%3A%2F%2Fimap2.mailboxsync.com%2Fredirect%2F
    &amp;response_mode=query
    &amp;scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send
    &amp;state=12345

    /*After user provides consent, exchanging auth code for refresh and access token */
    curl -XPOST https://login.microsoftonline.com/test.onmicrosoft.com/oauth2/v2.0/token -d &quot;client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03&amp;scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&amp;code=OAQABAAIAAAAm-06blBE1TpVMil8KPQ41HA4-ey0WVgK6WhqDDWBLoHBXdigqd8S_gE-uJBqH8f3z5U61GGQ_c_uJ__1n2r_IqwzTwjkmrd_VumomR-DaTz6tk0YUD6MdD5wZFC6ZET9N6clCnjSPnsBJ0Ee95qrLywipGqp9NL3Puea8AWZr06ltVrruvMpS9JOawOMgBMtbuUQjT_-C8EFmCz7yS-Iv-VjJYwlZ0S5jKnmRv9Iku8xt42VNjNsrRUVUJpvjbvRJWrmX6GYCD82VlQPntlwcTABqTsn-oNlFmFtbuE9fggTdvmRjq4diEPlwFHp0Fhjzolsmodh8tSIj0z2jHZXWFw3nbetaz_n71NSVc2DfKsKlr4sl-Zyew2xexOOwoHIkI33HVI3Hl0W-93zRkWMh5QxyDnU1R8pLVCU0GF1COThUvj1qaTpUW26nOgWdG1q0hXbLyhHe0HaLCY-RA0yg2fe49jCHNhOFiimkOgLrLD1a_-ICLhlAYkRUbd-aXdpbYZNOphvhNDkMqNILwk9LOHW3Cbsk6YDi1bwBTB2XTOvjyzb4uLz0_1exGc0XyA7wrSHf5l97k66sHgN6gEBKq-fgAOIgPMKPpovZ1ZiplS8Cd7ifcFmPfnAL5_ZJbt_0SCltNTX8v_qJRedCk8lNIoz18104eOdOyPyjFixlVi0MVpSFBoR6gEydFqoAeiwgAA&amp;state=12345&amp;session_state=1fab1545-2dc5-4102-b145-6258ea1ce97e&amp;state=12345&amp;redirect_uri=https%3A%2F%2Fimap2.mailboxsync.com%2Fredirect%2F&amp;client_secret=xxxx&amp;grant_type=authorization_code&quot;

    /*Exchanging refresh token for new access token*/
    curl -XPOST https://login.microsoftonline.com/test.onmicrosoft.com/oauth2/v2.0/token -d &quot;client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03&amp;scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&amp;refresh_token=OAQABAAAAAAAm-06blBE1TpVMil8KPQ41c8A8SyRZDLkMDX7Vm5ay9zjRE7DfM5Mwo26ooW2zeB6pgKGZr1KPKko7XMSHM8DJj71i8TnCOrg4doYCsuGKGCw5fC74KKtp2wLD7w1mJ4BQJqldj2-42VqN63x8U9wGibI_DqBTn2VxGxaHbtpIGtNwzR4xwQgDt9-BiotNIuYksxmF9ZCIr6X_uMLvI4DLsBXxe67YsSlvR9VrU8cH-xJddMGPaDyJisWDcR0uW0-yk0b24zYaj4G203ksEji5wiPbuT_PeBrjV5b638s26AX_nMfvXSAjJfq-jWHouynq-3VYZp63eJ2o36yQWDUUMAXZ6-OT2Kl9-n4Y2kVkGNdepp_RBBQ7BDceip7J2nf5tHQKDm4S3nPGkfUNIyzk3I5jurLm9tyK8bVHzSEMz8TSg5slj_6Vsk0Oa1BWwW4tgdwWjsUm344jTMpfhc9iGDbc98o_47v7BfnUYZCtWLFQQxd68i01JPZvcyEp4T8aE42rQVtR55DqN3_7NYfPQBzdK_qX1Ue4r7ptOs7BIrRQgvSvuTE--ATVYwqD6s_XEeBZnnX8x1_2-o0VOmnTP8_2FvhvhgCj93F7VK0yZ6PxrBaT9No5AyDVWkHmURxziLJWAl7qEaO0cLuKKWLew1zbzuld5ahhdmwFVYtFMEmOBNlikcP8-8WGgYcjIiw03975Vty4oxoYY4-DOvAWcupTn-E69VBSRFwfWo3y8M9XimKL7TyqoXKqQnMRnpqGezAtGnMWScKKVC179w5V5KVSxuQGeWqE-z6YfVT-16rEqBlkByyFrLyF3VvR5nYgAA&amp;grant_type=refresh_token&amp;client_secret=xxx&quot;

**IMAP DEBUG Log**

A1 AUTHENTICATE XOAUTH2 dXNlcj11c2VyXz...

A1 OK AUTHENTICATE completed.

A2 CAPABILITY

\* CAPABILITY IMAP4 IMAP4rev1 AUTH=PLAIN AUTH=XOAUTH2 SASL-IR UIDPLUS MOVE ID UNSELECT CLIENTACCESSRULES CLIENTNETWORKPRESENCELOCATION BACKENDAUTHENTICATE CHILDREN IDLE NAMESPACE LITERAL+

A2 OK CAPABILITY completed.

DEBUG IMAPS: AUTH: PLAIN

DEBUG IMAPS: AUTH: XOAUTH2

Connected to user_1@test.onmicrosoft.com using XOAUTH2

</details>



# 答案4
**得分**: 0

[javax.mail示例][1]
使用XOAUTH和O365 SMTP发送电子邮件

我只请求发送电子邮件所需的那些范围...(不使用Graph)。
可能我已经配置了一些不必要的权限。

  [1]: https://github.com/eino-makitalo/vesa-mailtest

<details>
<summary>英文:</summary>

[javax.mail example][1]
sending email using XOAUTH and O365 SMTP

I only ask those scopes needed for sending email... (not using Graph).
Probably I have configured some permissions not needed.


  [1]: https://github.com/eino-makitalo/vesa-mailtest

</details>



# 答案5
**得分**: 0

我有同样的问题 - 但是,当我使用 `Global Administrator` 帐户以 ####.onmicrosoft.com 的形式进行身份验证时,身份验证是成功的;但是当我使用我添加到相同租户的另一个帐户/用户,即 ####@outlook.com,它不起作用 **[身份验证失败]**。

<details>
<summary>英文:</summary>

I have the exact problem - However, The authentication is successful when I use the `Global Adminstrator` Account for authentication in the form of ####.onmicrosoft.com but when I use another account/user I added to the same tenant ####@outlook.com it does not work **[Authentication Unsuccessful]**

</details>



huangapple
  • 本文由 发表于 2020年5月5日 00:41:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/61597263.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定