[JAVA] Recevoir des e-mails avec l'authentification OAuth 2.0 sur Exchange Online

J'ai pu recevoir un email de l'article Dernière fois, mais au final je n'ai pas vu le jour dans mon travail. Environ un an plus tard, on parlait de développer une application pour recevoir de nouveaux courriels, et quand on m'a assuré que ce serait une victoire facile, le monde serait comme ça. .. ..

Si vous avez besoin de vous remodeler en moins d'un an, c'est à l'humanité que vous voulez vous occuper dès le début. J'ai entendu dire qu'il était nécessaire de jouer avec le côté Exchange Online si je vérifie à l'avance, donc je ne peux pas utiliser l'environnement d'exploitation actuel, j'ai demandé gratuitement Exchange Online pendant un mois, et c'est une authentification avancée basée sur OAuth 2.0 J'ai essayé de recevoir.

Soit dit en passant, l'application pour le développement est une application résidente qui sort périodiquement le courrier reçu par le compte de messagerie dédié à l'application dans un fichier texte, et comme méthode d'authentification, [flux ROPC recommandé de ne pas utiliser](https :: //docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth-ropc) est supposé, ce qui suit est un exemple d'implémentation.

Enregistrement de l'application

J'ai fait référence au Tutoriel pour le flux de traitement général et cette procédure.

  1. Connectez-vous au centre d'administration Azure Active Directory avec le compte que l'application utilise pour recevoir des e-mails, puis cliquez sur [Azure Active Directory] - [Register App] - [New Registration]. image.png

  2. Entrez le nom de l'application. Cette fois, l'application n'est utilisée que pour un compte spécifique, alors sélectionnez [Comptes inclus uniquement dans cet annuaire de l'organisation]. Je n'utilise pas l'URI de redirection, alors n'y touchez pas. Cliquez ensuite sur [Enregistrer]. image.png

  3. Réglez [Autoriser le flux client public] sur [Oui] et cliquez sur [Enregistrer]. image.png

  4. Dans [Ajouter une autorisation] de [Permission API], ajoutez [IMAP.AccessAsUser.All] à partir de [Autorisation déléguée] de [Microsoft Graph]. Cette fois, le compte connecté est également un administrateur, il vous suffit donc de cliquer sur [Donner le consentement de l'administrateur à ~]. image.png

Création de l'application sous-jacente

J'ai utilisé Spring Boot 2.3.4 et Kotlin pour simplifier. Ajoutez uniquement Java Mail Sender (c'est-à-dire spring-boot-starter-mail) en tant que dépendance de l'initialiseur spring et ajoutez la bibliothèque d'authentification Microsoft pour Java à pom.xml après la création d'un projet.

pom.xml


<dependency>
  <groupId>com.microsoft.azure</groupId>
  <artifactId>msal4j</artifactId>
  <version>1.7.1</version>
</dependency>

Implémentez CommandLineRunner et écrivez le processus dans la méthode d'exécution.

@SpringBootApplication
class SampleMailApplication : CommandLineRunner {
  override fun run(vararg args: String?) {
    //la mise en oeuvre
  }
}

Obtenez un jeton d'accès

Cette procédure du tutoriel référencé ci-dessus n'est pas cool. Qu'est-ce que "Open App.xaml", le reste de l'article C #? .. .. Je n'avais pas d'autre choix que de le rechercher sur le net et il a commencé à fonctionner avec le code suivant.

import com.microsoft.aad.msal4j.PublicClientApplication
import com.microsoft.aad.msal4j.UserNamePasswordParameters

//Omis
override fun run(vararg args: String?) {
  //Spécifiez l'ID de l'application sur la page de présentation de l'application enregistrée
  val applicationId = "..."
  // ...Spécifiez l'ID du répertoire sur la page de présentation de la pièce
  val authEndpoint = "https://login.microsoftonline.com/.../oauth2/v2.0/authorize"
  //Précisez selon le protocole à utiliser
  val scope = setOf("https://outlook.office365.com/IMAP.AccessAsUser.All",
    "https://outlook.office365.com/SMTP.Send")
  //Spécifiez l'adresse e-mail du compte
  val username = "..."
  //Spécifiez le mot de passe du compte
  val password = "..."

  val pca = PublicClientApplication.builder(applicationId)
    .authority(authEndpoint)
    .build()

  val parameters = UserNamePasswordParameters
    .builder(scope, username, password.toCharArray())
    .build()
  val result = pca.acquireToken(parameters).join()
  println("Jeton d'accès: ${result.accessToken()}")

courrier entrant

var props = Properties()
//OAuth 2 pour l'authentification.Utiliser 0
props["mail.imaps.auth.mechanisms"] = "XOAUTH2"
var session: Session = Session.getInstance(props)
val store: Store = session.getStore("imaps")
//Utiliser le jeton d'accès pour le mot de passe
store.connect("outlook.office365.com", 993, username, result.accessToken())
val folderInbox: Folder = store.getFolder("INBOX")
folderInbox.open(Folder.READ_ONLY)
folderInbox.messages.forEach { println("matière: ${it.subject}") }

Le premier point est mail.imaps.auth.mechanisms [Description](https://github.com/eclipse-ee4j/mail/blob/c3096cbeaf566f36998e96ff384378059f291ce8/mail/src/main/java/com/sun/mail/imap Selon /package.html#L405-L410), la valeur par défaut correspond à toutes les authentifications prises en charge sauf XOAUTH2, et Exchange Online utilise l'authentification de base. Par conséquent, spécifiez XOAUTH2 pour activer l'authentification OAuth 2.0.

Vous pouvez désormais recevoir des e-mails avec l'authentification OAuth 2.0 en spécifiant simplement le jeton d'accès au lieu du mot de passe.

(Supplément) Envoyer un mail

Pour le moment, j'aimerais essayer l'authentification OAuth 2.0 pour l'authentification de base de SMTP, qui sera bientôt abolie. Cependant, loin de l'authentification OAuth 2.0, même de l'authentification de base

javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful

N'est-ce pas![Le SMTP authentifié dans la boîte aux lettres est activé](https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission#use-the -microsoft-365-admin-center-to-enable-or-disable-smtp-auth-on-specific-mailboxes). .. ..

La page indique: «Si votre stratégie d'authentification désactive l'authentification SMTP de base, vos clients ne pourront pas utiliser le protocole d'authentification SMTP, même si vous activez les paramètres décrits dans cet article». Activez les valeurs par défaut] sur [Non]](https://docs.microsoft.com/ja-jp/azure/active-directory/fundamentals/concept-fundamentals-security-defaults) pour garantir une transmission réussie des e-mails Cependant, lorsque je redéfinis [Activer les paramètres de sécurité par défaut] sur [Oui], l'erreur ne se produit plus. (Il est indéniable que quelque chose d'autre a été falsifié ...)

Je ne sais pas ce que c'est ...

Pour le moment, la logique de transmission réussie est également décrite.

val props = Properties()
props["mail.smtp.auth"] = "true"
props["mail.smtp.auth.mechanisms"] = "XOAUTH2";
props["mail.smtp.starttls.enable"] = "true"
val session = Session.getInstance(props)
val transport = session.getTransport("smtp")
transport.connect("smtp.office365.com", 587, username, result.accessToken())

val sendMessage = MimeMessage(session)
sendMessage.addRecipients(Message.RecipientType.TO, username)
sendMessage.setFrom(username)
sendMessage.subject = "Envoyer"
sendMessage.setText("Test de transmission")

transport.sendMessage(sendMessage, sendMessage.allRecipients)

En outre, bien que la transmission elle-même soit terminée, la livraison finale n'a pas été effectuée avec "550 5.7.501 Service indisponible. Abus de spam détecté à partir de la plage IP." De la destination. En effet, les e-mails du domaine onmicrosoft.com sont filtrés comme spam, et même si vous essayez de les envoyer depuis Outlook, vous obtiendrez le même résultat, donc je pense qu'il n'y a pas de problème avec la logique.

Recommended Posts

Recevoir des e-mails avec l'authentification OAuth 2.0 sur Exchange Online
Authentification Oauth2 avec Spring Cloud Gateway
SSO avec GitHub OAuth dans l'environnement Spring Boot 1.5.x