Xoauth2 ошибка подтверждения подлинности

Recently the support for OAuth 2.0 for IMAP and SMTP in the Exchange Online has been announced.
Following the guide I’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.

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

The scopes, requests from code:

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"
);

I successfully receive the access and refresh tokens:

{
    "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": "edited",
    "refresh_token": "edited",
    "id_token": "edited"
}

Here’s the code, used to connect to 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 = "access_token_received_on_previous_step";

final Store store = session.getStore("imaps");
store.connect("outlook.office365.com", 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 "outlook.office365.com", 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=<non-null>
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 "main" 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("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 = "access_token_received_on_previous_step";

Transport transport = session.getTransport("smtp");
transport.connect("smtp.office365.com", 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 "smtp.office365.com", 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 "smtp.office365.com", 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 "SIZE", arg "157286400"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
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 "SIZE", arg "157286400"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN XOAUTH2"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.office365.com, user=user@domain.onmicrosoft.com, password=<non-null>
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 "main" 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:

enter image description here

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

enter image description here

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<String> SCOPES = Arrays.asList(
    "offline_access",
    "https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All",
    "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send"
);

Which gave me the token below:

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

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<String> SCOPES = Arrays.asList(
        "offline_access",
        "User.Read",
        "Mail.ReadWrite",
        "https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All",
        "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send"
);

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

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

Which led to the result I got previously:

A1 NO AUTHENTICATE failed.

Trying all the scopes to be as URLs:

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

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

{
    "error": "invalid_request",
    "error_description": "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.rnTrace ID: c3282396-6231-4e11-8300-77bc2ca57f00rnCorrelation ID: 5f5145bf-7114-4e6c-ab11-30e7ff84a056rnTimestamp: 2020-05-06 08:08:48Z",
    "error_codes": [
        28000
    ],
    "timestamp": "2020-05-06 08:08:48Z",
    "trace_id": "c3282396-6231-4e11-8300-77bc2ca57f00",
    "correlation_id": "5f5145bf-7114-4e6c-ab11-30e7ff84a056"
}

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

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

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

{
    "token_type": "Bearer",
    "scope": "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",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1..."
}

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:

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

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

Recently, I am trying to get e-mails from Gmail, using XOAuth2 protocol.
Especially, I am using «OAuth2Authenticator.java» from https://code.google.com/p/google-mail-oauth2-tools/downloads/list.

But, I always get an invalid credential error like the follwoing:

A1 NO [ALERT] Invalid credentials (Failure)
Exception in thread «main» javax.mail.AuthenticationFailedException: [ALERT] Invalid credentials (Failure)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:566)
at javax.mail.Service.connect(Service.java:265)

Before reading, due to the limitation of putting a link, I cannot write «httoo://» so that please think of that this http header is front of some url information.

Before posting this question, I think I looked most of the articles about this one. Many articles are about using OAuth1.0 (deprecated) But, I still cannot figure out how I can make it work with OAuth2 & XOAuth2. I appreciate any suggestion/helps.

The following is the steps I am taking:

  1. get an access token through OAuth2 with the scope of mail.google.com/

  2. just put this access token & gmail account (e.g. test@gmail.com) into «OAuth2Authenticator.java».

After this procedure, I always get invalid credential.

The interesting stuff is that I can get unread mails through Feed URL (i.e. https://mail.google.com/mail/feed/atom) which is specified in Google OAuth2.0 Playground.

This indicates that I am sure that I get the correct access token. But, does not work at all for IMAP with this sample code.

Actually, the scope «mail.google.com/» is not included in the list of Google OAuth2.0 Playground.

For getting access token for XOAuth2, is there any other special way to get access token?

For the official page about XOAuth2, we need to use base64 to encode the access token.
But, I think the sample code is doing this procedure.

Also, SMTP of this sample did not work at all. But, after changing the properties, I could make it work. Is this code old?
But, unfortunately, what I need is IMAP. But, after trying setting some different/new properties, IMAP does not work at all….

I am stuck on this problem for a long time. So, I posted this question.
I really appreciate any suggestion/helps.

Regards

Recently, I am trying to get e-mails from Gmail, using XOAuth2 protocol.
Especially, I am using «OAuth2Authenticator.java» from https://code.google.com/p/google-mail-oauth2-tools/downloads/list.

But, I always get an invalid credential error like the follwoing:

A1 NO [ALERT] Invalid credentials (Failure)
Exception in thread «main» javax.mail.AuthenticationFailedException: [ALERT] Invalid credentials (Failure)
at com.sun.mail.imap.IMAPStore.protocolConnect(IMAPStore.java:566)
at javax.mail.Service.connect(Service.java:265)

Before reading, due to the limitation of putting a link, I cannot write «httoo://» so that please think of that this http header is front of some url information.

Before posting this question, I think I looked most of the articles about this one. Many articles are about using OAuth1.0 (deprecated) But, I still cannot figure out how I can make it work with OAuth2 & XOAuth2. I appreciate any suggestion/helps.

The following is the steps I am taking:

  1. get an access token through OAuth2 with the scope of mail.google.com/

  2. just put this access token & gmail account (e.g. test@gmail.com) into «OAuth2Authenticator.java».

After this procedure, I always get invalid credential.

The interesting stuff is that I can get unread mails through Feed URL (i.e. https://mail.google.com/mail/feed/atom) which is specified in Google OAuth2.0 Playground.

This indicates that I am sure that I get the correct access token. But, does not work at all for IMAP with this sample code.

Actually, the scope «mail.google.com/» is not included in the list of Google OAuth2.0 Playground.

For getting access token for XOAuth2, is there any other special way to get access token?

For the official page about XOAuth2, we need to use base64 to encode the access token.
But, I think the sample code is doing this procedure.

Also, SMTP of this sample did not work at all. But, after changing the properties, I could make it work. Is this code old?
But, unfortunately, what I need is IMAP. But, after trying setting some different/new properties, IMAP does not work at all….

I am stuck on this problem for a long time. So, I posted this question.
I really appreciate any suggestion/helps.

Regards

Recently the support for OAuth 2.0 for IMAP and SMTP in the Exchange Online has been announced.
Following the guide I’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.

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

The scopes, requests from code:

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"
);

I successfully receive the access and refresh tokens:

{
    "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": "edited",
    "refresh_token": "edited",
    "id_token": "edited"
}

Here’s the code, used to connect to 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 = "access_token_received_on_previous_step";

final Store store = session.getStore("imaps");
store.connect("outlook.office365.com", 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 "outlook.office365.com", 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=<non-null>
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 "main" 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("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 = "access_token_received_on_previous_step";

Transport transport = session.getTransport("smtp");
transport.connect("smtp.office365.com", 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 "smtp.office365.com", 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 "smtp.office365.com", 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 "SIZE", arg "157286400"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
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 "SIZE", arg "157286400"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN XOAUTH2"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.office365.com, user=user@domain.onmicrosoft.com, password=<non-null>
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 "main" 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:

enter image description here

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

enter image description here

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<String> SCOPES = Arrays.asList(
    "offline_access",
    "https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All",
    "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send"
);

Which gave me the token below:

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

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<String> SCOPES = Arrays.asList(
        "offline_access",
        "User.Read",
        "Mail.ReadWrite",
        "https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All",
        "https%3A%2F%2Foutlook.office365.com%2FSMTP.Send"
);

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

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

Which led to the result I got previously:

A1 NO AUTHENTICATE failed.

Trying all the scopes to be as URLs:

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

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

{
    "error": "invalid_request",
    "error_description": "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.rnTrace ID: c3282396-6231-4e11-8300-77bc2ca57f00rnCorrelation ID: 5f5145bf-7114-4e6c-ab11-30e7ff84a056rnTimestamp: 2020-05-06 08:08:48Z",
    "error_codes": [
        28000
    ],
    "timestamp": "2020-05-06 08:08:48Z",
    "trace_id": "c3282396-6231-4e11-8300-77bc2ca57f00",
    "correlation_id": "5f5145bf-7114-4e6c-ab11-30e7ff84a056"
}

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

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

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

{
    "token_type": "Bearer",
    "scope": "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",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1..."
}

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:

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

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

#authentication #oauth-2.0 #outlook #imap #javax.mail.address

Вопрос:

мы пытаемся войти в систему outlook.com в нашем приложении с помощью oauth2.0 мы выполнили регистрацию приложения AAD. Приложение успешно аутентифицирует пользователя и отвечает с помощью access_token, теперь мы хотели прочитать электронные письма с сервера imap, и здесь мы получаем сбой, пожалуйста, попробуйте помочь нам в этом.

Пожалуйста, найдите ниже ошибку, которую мы получаем.

  • ХОРОШО, служба Microsoft Exchange IMAP4 готова. [UABOADIAUABSADAAMQBDAEEAMAAwADYAMgAuAEkATgBEAFAAUgBEADAAMQAuAFAAUgBPAEQALgBPAFUAVABMAE8ATwBLAC4AQwBPAE0A] ВОЗМОЖНОСТЬ A0
  • ВОЗМОЖНОСТЬ IMAP4 IMAP4rev1 АУТЕНТИФИКАЦИЯ=ОБЫЧНАЯ АУТЕНТИФИКАЦИЯ=XOAUTH2 ИДЕНТИФИКАТОР UIDPLUS SASL-IR ОТМЕНЯЕТ ВЫБОР ДОЧЕРНЕГО ЛИТЕРАЛА ПРОСТАИВАЮЩЕГО ПРОСТРАНСТВА ИМЕН A0 ОК ВОЗМОЖНОСТЬ завершена. Отладка IMAPS: аутентификация: обычная отладка IMAPS: для auth: XOAUTH2 debug в IMAPS: protocolConnect login, то host=outlook.office365.com, user=siccsanda@outlook.com, пароль= «отладка» IMAPS: механизм простой отключена по недвижимости: почта.imaps.авт.равнины.отключить отладку IMAPS: механизм входа в систему не поддерживается сервером отладки IMAPS: механизм NTLM не поддерживается сервером аутентификации А1 XOAUTH2 dXNlcj1zaWNjc2FuZGFAb3V0bG9vay5jb20BYXV0aD1CZWFyZXIgRXdCd0E4bDZCQUFVNms3K1hWUXprR3lNdjdWSEIvaDRjSGJKWVJBQUFhbWdZWE81azJ2NEVQYmduSE5BWUcyNENWYXJ4V2dEek9lZ2E2S0J0SGZKcDVkV1hkK3E5T2ExSEJocitIQW1JWVJBRkh6NWxFRWJJRFdGZVF6MGU5U0pRNzZzVnYwUVhXVFFRRUExSktRSmdHdm51Z3QrV2dvd1pJUUxmcVJBQmh2Mm02WWk4bDlWU1FGS1pzV2lpY000blYzWElza0RyYWlWRTNjU2ZMS0tmK09MUDg4OHNCNnVPbzlOWDNXYnZFWUdZTGVMbVpjUG5NOUlrK3MzazhYQWtpOWY2VTl6MGFjUHdKQWRsbk9JZElvNzJQYjhYeXJmVDB6OHpFV2ExRm8xVVpiUHJvdnIrakd1NTJhcjMyaVlZWnpkSDhxaGhZRFRFcTJOQnhOUDVaV1dsbTZQV2lYR2ZhZ05EL2k3RWxDSFJRZ0twdFN2dDMySEpaN3VqRkFEWmdBQUNDYTdqZGVnM3cza1FBSUdpR09YREFaYmdhK3ZDempqeERwT29wZExERTQzaldhbHRVSHJDVk8zS1BSMFFzMzV5SDNTeWNaK0xqTEl1U043VVZheWozUHZWejZ1bDZPdkxkSUozVkhpcjBBbTRxeDlvWjRobnBLRG0yc2Q2akptUWxtVFFHRmhqTjVLN0poSmUyb1VvMzJZNHlrYU1vNFRPQkpxc3ZuOCtja0dCekRHYUdsWjltU0dsZmpJWDdIR29HbnQ4S2NmOEhsTFdnSzhpVWkvOWJoTjV4MnNNSWM0YzhWWlRlUkpJbXNrQUNQbnRoSGoybUNHeXpmRi9qTXkvbnV4VFNOVE0wby9QS045ME00M1VGT3hDSk5MRldiVkkwQ3RzcDNWRGZ6MWVZejdZV1NtLzNtSlhkSk02bkFIeWZRQnFJZTB3Q3A1aU9pU1J2R3pyV0o1WXlVRWNWV1VyRndxQjBQbXFUMEJFeVBOOVhLR0FZQmlFQ2hEanpqS1NjUFRNM29jbEdCQld6V0FNYzF4bUVXTktsSm5Ma0s3N3Z3S2NkYklTa1c1WWdBbU84ZWZrUExIdU16UnpuQ2o3NTQzS0dCOEpFUTlZSUx0TkJQMTZmcjFYR1NnVkFwb2tkUU1wdG1YU2dFd2pJZnozKzgrWDE0MFJqblZaYjdrbzBQNnJsQzNnWkRVdEdoQ3I2Mm15ZzN2U1pZaUt2UzBrVkR2ZDhFbUJ3N1BUZGVlWFZEWXZYc2gycTJMY2NleEVhOXJuSHFra1g4cVVRNWp2U2RvT2JTL3VGM1hZL1VuajlHZUFhbERCdEZvUXhsREkvaU5aeGVoS2FFSDFydE5ncTI2by9oSW1NNzZDb3BwcCtzb0p3dUJQNE5wbDFHY1RQNEdycjFURVkwbGRTTW4zNDdwODE2WEZJWk1FSVJiSEpoekR6VVNIRVQxbjFRbEZyOUhRZlVVSHhCOWtPMWlzVzdEaDdaSFhMSnBBRCtiTHc3SGpuY3JYcHBXdkEydFRzclNWVVkwSDhJS2lpU0hBZz09AQE=
    A1 NO AUTHENTICATE failed.

Пожалуйста, найдите код для подключения:

  properties.put("mail.imaps.host", "outlook.office365.com");
        properties.put("incomingHost", "outlook.office365.com");
        properties.put("outgoingHost", "smtp.office365.com");
        properties.put("mail.imaps.ssl.enable", "true");
        //properties.put("mail.imaps.sasl.enable", "true");
        properties.put("mail.imaps.sasl.mechanisms", "XOAUTH2");
       // properties.put("mail.imap.auth.login.disable", "true");
        properties.put("mail.imaps.auth.plain.disable", "true");
        //properties.put("mail.imaps.auth.plain.disable", "true");
        properties.put("mail.debug", "true");
        properties.put("mail.debug.auth", "true");
        properties.setProperty("mail.imaps.ssl.trust", "*");
        properties.setProperty("mail.smtp.starttls.enable","true");
       
        this.store = session.getStore("imaps");
     store.connect("outlook.office365.com", "abc@outlook.com", "access_token");
 

Ответ №1:

Я также борюсь с XOAUTH. В своем коде я задаю свойства:

 Mail property mail.imaps.auth.plain.disable: true
Mail property mail.imaps.auth.mechanisms: XOAUTH2
Mail property mail.imaps.port: 993
Mail property mail.store.protocol: imaps
Mail property mail.imaps.ssl.enable: true
Mail property mail.imaps.partialfetch: false
Mail property mail.mime.decodetext.strict: false
Mail property mail.imaps.peek: true
Mail property mail.mime.charset: UTF-8
 

что привело (по крайней мере) к входу в систему XOAUTH

 DEBUG IMAPS: AUTHENTICATE XOAUTH2 command result: A1 NO AUTHENTICATE failed.
 

Недавно было объявлено о поддержке OAuth 2.0 для IMAP и SMTP в Exchange Online. Следуя руководству, я настроил разрешения приложений и IMAP и SMTP-соединение. Приложение настроено какAccounts in any organizational directory (Any Azure AD directory - Multitenant)и использует поток кода авторизации.

Нижеуказанные URL-адреса используются для авторизации:

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

Были добавлены следующие делегированные области Microsoft Graph:

Объемы, запросы из кода:

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": "edited",
    "refresh_token": "edited",
    "id_token": "edited"
}

Вот код, используемый для подключения к 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 = "[email protected]";
String accessToken = "access_token_received_on_previous_step";

final Store store = session.getStore("imaps");
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: 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 "outlook.office365.com", 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, [email protected], password=<non-null>
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: [email protected]
DEBUG IMAPS: SASL callback 1: [email protected]
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 = "[email protected]";
String accessToken = "access_token_received_on_previous_step";

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

Что дает результат ниже:

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 "smtp.office365.com", 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 "smtp.office365.com", 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 "SIZE", arg "157286400"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "STARTTLS", arg ""
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
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 "SIZE", arg "157286400"
DEBUG SMTP: Found extension "PIPELINING", arg ""
DEBUG SMTP: Found extension "DSN", arg ""
DEBUG SMTP: Found extension "ENHANCEDSTATUSCODES", arg ""
DEBUG SMTP: Found extension "AUTH", arg "LOGIN XOAUTH2"
DEBUG SMTP: Found extension "8BITMIME", arg ""
DEBUG SMTP: Found extension "BINARYMIME", arg ""
DEBUG SMTP: Found extension "CHUNKING", arg ""
DEBUG SMTP: Found extension "SMTPUTF8", arg ""
DEBUG SMTP: protocolConnect login, host=smtp.office365.com, [email protected], password=<non-null>
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 "main" 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)

Что еще пробовал:

  • определение областей как https://graph.microsoft.com/SMTP.Send и просто SMTP.Send
  • с помощью https://login.microsoftonline.com/common/ URL для аутентификации

Результат всегда один и тот же.

Я что-то делаю неправильно или где-то есть ошибка в поддержке со стороны Microsoft?

Обновление 1:

Пробовал из командной строки, но результат тот же:

$ 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

Обновление 2:

Пытался создать новое приложение на портале Azure со следующими разрешениями:

И получение следующего экрана при попытке дать согласие на области:

Это странно, потому что в разрешениях портала Azure не указано, что требуется согласие администратора, а моя предыдущая регистрация приложения не показывает такой экран, когда запрашиваются области IMAP и SMTP.

Обновление 3:

Благодаря комментариям к этой публикации я попробовал следующие области:

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

Что дало мне токен ниже:

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

IMAP / SMTP аутентификация прошла успешно, и я смог прочитать входящие + отправить электронное письмо!

Но для моего приложения мне также нужна пара других областей для использования некоторых конечных точек API MS Graph (чтение профиля пользователя, подписка на сообщения и удаление сообщений).

Поэтому я пробовал разные прицелы:

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

Это дало токен (обратите внимание, что значение области отличается от токена, который фактически работал, разрешения не имеют URL-адреса Outlook):

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

Что привело к результату, который я получил ранее:

A1 NO AUTHENTICATE failed.

Попытка сделать все области как URL-адреса:

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

Приводит к следующей ошибке при получении токена (этап согласия прошел успешно):

{
    "error": "invalid_request",
    "error_description": "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.rnTrace ID: c3282396-6231-4e11-8300-77bc2ca57f00rnCorrelation ID: 5f5145bf-7114-4e6c-ab11-30e7ff84a056rnTimestamp: 2020-05-06 08:08:48Z",
    "error_codes": [
        28000
    ],
    "timestamp": "2020-05-06 08:08:48Z",
    "trace_id": "c3282396-6231-4e11-8300-77bc2ca57f00",
    "correlation_id": "5f5145bf-7114-4e6c-ab11-30e7ff84a056"
}

И при попытке всех областей иметь график microsoft (скопированный с портала Azure)

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

Верните следующий токен (без токена обновления, хотя был запрошен offline_access)

{
    "token_type": "Bearer",
    "scope": "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",
    "expires_in": 3599,
    "ext_expires_in": 3599,
    "access_token": "eyJ0eXAiOiJKV1..."
}

Безуспешно:

A1 NO AUTHENTICATE failed.

Таким образом, похоже, что если вы не укажете URL-адрес Outlook для области, он, вероятно, будет принят как Graph, который не разрешает авторизацию через IMAP и SMTP.

Обновление 4:

Запрашивая все области, которые мне нужны на этапе согласия, затем получал первый токен доступа только с областями Graph, а второй — с использованием конечной точки токена обновления, определяющей области Outlook, — это сработало. Метод обновления токена используется для получения второго токена доступа, потому что если вы попытаетесь получить токен доступа с помощью кода аутентификации, вы получите следующую ошибку:

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

Так что нет, мне нужно будет использовать два отдельных токена в зависимости от того, каким ресурсом мне нужно управлять.

Обновление 5:

Если это все еще не работает — проверьте, включена ли в вашей организации безопасность по умолчанию — они отключают аутентификацию POP/IMAP/SMTP для учетных записей — 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

I am using xoauth2 module to generate an xoauth2 token to connect via imap to gmail and I’m getting this error:

`

[09:50:28.806] [LOG] [connection] Connected to host
[09:50:28.873] [LOG] <= '* OK Gimap ready for requests from 31.154.25.42 q4mb701
07656lfe'
[09:50:28.881] [LOG] => 'A0 CAPABILITY'
[09:50:29.067] [LOG] <= '* CAPABILITY IMAP4rev1 UNSELECT IDLE NAMESPACE QUOTA ID
 XLIST CHILDREN X-GM-EXT-1 XYZZY SASL-IR AUTH=XOAUTH2 AUTH=PLAIN AUTH=PLAIN-CLIE
NTTOKEN AUTH=OAUTHBEARER AUTH=XOAUTH'
[09:50:29.069] [LOG] <= 'A0 OK Thats all she wrote! q4mb70107656lfe'
[09:50:29.073] [LOG] => 'A1 AUTHENTICATE XOAUTH2 ******************************************
****************************************************************************************************************************
********************************************************************************='
[09:50:29.374] [LOG] <= '+ eyJzdGF0dXMiOiI0MDAiLCJzY2hlbWVzIjoiQmVhcmVyIiwic2Nvc
GUiOiJodHRwczovL21haWwuZ29vZ2xlLmNvbS8ifQ=='
[09:50:29.377] [LOG] => 'rn'
[09:50:29.534] [LOG] <= 'A1 NO [AUTHENTICATIONFAILED] Invalid credentials (Failu
re)'
[09:50:29.537] [ERROR] ERROR Imap:Error: Invalid credentials (Failure)
[09:50:29.755] [LOG] [connection] Ended
[09:50:29.756] [LOG] Imap: Connection ended
[09:50:29.758] [LOG] [connection] Closed`

here is my connection code :

this.setImap = function(connParams) {
    //----------------------------------------------
    console.log(connParams);
    xoauth2gen = xoauth2.createXOAuth2Generator({
      user: connParams.user",
      clientId: configAuth.googleAuth.clientID,
      clientSecret: configAuth.googleAuth.clientSecret,
      refreshToken: connParams.refresh_token,
      accessToken: connParams.access_token,
       customPayload: {
      "access_type": "offline"
    }
    });

xoauth2gen.getToken(function(err, token) {
  if (err) {
    return console.log(err);
  }
  console.log("AUTH XOAUTH2 " + token);
  connParams.xoauth2 = token;
});

connParams = {
  id: 13,
  user: connParams.user,
  xoauth2: connParams.xoauth2,
  host: 'imap.gmail.com',
  port: 993,
  tls: 1,
  debug: console.log
}
//------------------------------------------- 
connParams.tlsOptions = {
  rejectUnauthorized: false
};

console.log(connParams);



self.imap = new Imap(connParams);

this.imap.once('ready', function() {
  console.log('Imap: ready');
  self.openInbox();
});

this.imap.once('error', function(err) {
  console.error("ERROR Imap:" + err);
});

this.imap.once('end', function() {
  console.log('Imap: Connection ended');
});
};

Checked a million time the details :(

here is the scope I’m using :

scope: ['profile', "https://mail.google.com/" ]

I would appreciate any help, Thanks!!

Понравилась статья? Поделить с друзьями:

Не пропустите эти материалы по теме:

  • Яндекс еда ошибка привязки карты
  • Xnview ошибка при открытии файла
  • Xmlhttprequest ошибка 500
  • Xmlhttprequest обработка ошибок
  • Xrengine exe ошибка приложения 0xc000007b сталкер зов припяти

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии