Сбой аутентификации Office 365 XOAUTH2 для IMAP и SMTP - PullRequest
0 голосов
/ 04 мая 2020

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

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

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

enter image description here

Области, запросы от кода:

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

Я успешно получаю доступ и повторно sh токены:

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

, который генерирует следующий вывод:

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)

И для подключения к 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);

, который обеспечивает вывод ниже:

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)

То, что я тоже пробовал:

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

Я что-то не так делаю или есть ошибка в поддержке этого со стороны 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 со следующими разрешениями:

enter image description here

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

enter image description here

Это странно, поскольку разрешения на портале 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 (читайте профиль пользователя, я подписка ssages и удаление сообщений).

Итак, я попробовал разные области действия:

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

Это дало токен (обратите внимание, что значение области действия отличается от того, который на самом деле работал, разрешения не 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..."
}

Что привело к полученному ранее результату:

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.\r\nTrace ID: c3282396-6231-4e11-8300-77bc2ca57f00\r\nCorrelation ID: 5f5145bf-7114-4e6c-ab11-30e7ff84a056\r\nTimestamp: 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"
);

Вернуть следующий токен (без refre sh токен, хотя запрашивается 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.

Ответы [ 3 ]

1 голос
/ 08 мая 2020

IMAP, области SMTP предназначены для ресурса Exchange, а не для Graph. Тогда как User.Read, Mail.ReadWrite предназначены для ресурса Graph.

Мы не поддерживаем создание токенов, предназначенных для двух ресурсов. Следовательно, ошибка «Предоставленное значение для области входных параметров недопустимо, поскольку она содержит более одного ресурса».

Вы должны сгенерировать два токена по отдельности с помощью двух вызовов to / token. 1. Один с IMAP, области SMTP, созданные для ресурса Exchange. 2. Другой с областями Graph (User.Read, Mail.ReadWrite) предназначен для ресурса Graph.

0 голосов
/ 09 мая 2020

пример javax.mail отправка электронной почты с использованием XOAUTH и O365 SMTP

Я запрашиваю только те области, которые необходимы для отправки электронной почты ... (без использования Graph). Возможно, я настроил некоторые разрешения, которые не нужны.

0 голосов
/ 06 мая 2020

@ ldniov, я не мог найти ничего отличного от того, что я сделал. Предоставляя команды, которые я использовал ниже для справки.

/* 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
&response_type=code
&redirect_uri=https%3A%2F%2Fimap2.mailboxsync.com%2Fredirect%2F
&response_mode=query
&scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send
&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 "client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03&scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&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&state=12345&session_state=1fab1545-2dc5-4102-b145-6258ea1ce97e&state=12345&redirect_uri=https%3A%2F%2Fimap2.mailboxsync.com%2Fredirect%2F&client_secret=xxxx&grant_type=authorization_code"

/*Exchanging refresh token for new access token*/
curl -XPOST https://login.microsoftonline.com/test.onmicrosoft.com/oauth2/v2.0/token -d "client_id=0c56e5c5-0a9e-4ddf-a931-54de274c2e03&scope=offline_access%20https%3A%2F%2Foutlook.office365.com%2FIMAP.AccessAsUser.All%20https%3A%2F%2Foutlook.office365.com%2FSMTP.Send&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&grant_type=refresh_token&client_secret=xxx"

Журнал отладки IMAP

A1 AUTHENTICATE XOAUTH2 dXNlcj11c2VyXz ...

A1 OK AUTHENTICATE завершен.

A2 ВОЗМОЖНОСТЬ

* ВОЗМОЖНОСТЬ IMAP4 IMAP4rev1 AUTH = PLAIN AUTH = XOAUTH2 SASL-IR UIDPLUS MOVE ID НЕ ВЫБИРАЕТСЯ CLIENTACCESSRULES CLIENTNETWORKPRESENCELCATION

*

IMAPS отладки: AUTH: PLAIN

IMAPS отладки: AUTH: XOAUTH2

Подключено к user_1@test.onmicrosoft.com с использованием XOAUTH2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...