Java javax.mail, msal4j Oauth2 отправляет электронную почту с помощью Office 365
Я хотел бы отправить электронное письмо. Я использую Java 1.8, com.microsoft.aad.msal4j и javax.mail. Однако я получаю следующую ошибку. Что бы я ни указывал:
5.7.3 Authentication unsuccessful [........PROD.OUTLOOK.COM 2023-10-07T15:04:28.150Z ....]
Exception in thread "main" javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful [........PROD.OUTLOOK.COM 2023-10-07T15:04:28.150Z ...]
at com.sun.mail.smtp.SMTPTransport$Authenticator.authenticate(SMTPTransport.java:947)
at com.sun.mail.smtp.SMTPTransport.authenticate(SMTPTransport.java:858)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:762)
at javax.mail.Service.connect(Service.java:366)
К сожалению, вы вряд ли найдете документацию, и тестовые реализации здесь тоже не очень хороши.
Я использую:
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>msal4j</artifactId>
<version>1.13.10</version>
</dependency>
У меня работает, но только для .default или https://outlook.office365.com/.default в качестве области.
Вот моя реализация (короткая версия):
public static void main(String[] args) throws ExecutionException, InterruptedException, MessagingException, MalformedURLException {
Properties props = new Properties();
props.put("mail.smtp.port", "587");
props.put("mail.smtp.host", "smtp.office365.com");
props.put("mail.imap.ssl.enable", "true");
props.put("mail.smtp.auth.mechanisms", "XOAUTH2");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
props.put("mail.debug.auth", "true");
props.put("mail.debug", "true");
props.put("mail.smtp.auth.xoauth2.disable", "false");
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth.login.disable", "true");
props.put("mail.smtp.auth.plain.disable", "true");
Session session = Session.getInstance(props);
Transport transport = session.getTransport("smtp");
IAuthenticationResult t = tokenFor("https://outlook.office365.com/.default").get();
String token = t.accessToken();
transport.connect("smtp.office365.com", 587, "user@foo.com", token);
transport.send(new MimeMessage(session));
}
private static CompletableFuture<IAuthenticationResult> tokenFor(String... scopes) throws MalformedURLException {
String tenantId = "...";
String clientId = "...";
String url = "https://login.microsoftonline.com/%s/oauth2/v2.0/token";
String authority = String.format(url, tenantId);
String clientSecret = "...";
IClientCredential secret = ClientCredentialFactory.createFromSecret(clientSecret);
ConfidentialClientApplication.Builder app = ConfidentialClientApplication.builder(clientId, secret)
.authority(authority);
ClientCredentialParameters.ClientCredentialParametersBuilder clientCredentialParam =
ClientCredentialParameters.builder
(new HashSet<>(Arrays.asList(scopes)));
return app.build().acquireToken(clientCredentialParam.build());
}
Может кто-нибудь попробовать это?