[JAVA] Empfangen Sie E-Mails mit OAuth 2.0-Authentifizierung in Exchange Online

Ich konnte eine E-Mail vom Artikel Letztes Mal erhalten, aber am Ende sah ich nicht das Licht der Welt in meiner Arbeit. Ungefähr ein Jahr später war die Rede davon, eine App für den Empfang neuer E-Mails zu entwickeln, und als mir versichert wurde, dass dies ein einfacher Gewinn sein würde, würde die Welt so aussehen. .. ..

Wenn Sie in weniger als einem Jahr umbauen müssen, ist es die Menschlichkeit, mit der Sie sich von Anfang an befassen möchten. Ich habe gehört, dass es notwendig ist, mit der Exchange Online-Seite zu spielen, wenn ich dies im Voraus überprüfe, damit ich die aktuelle Betriebsumgebung nicht verwenden kann. Ich habe einen Monat lang kostenlos Exchange Online beantragt und es handelt sich um eine erweiterte Authentifizierung basierend auf OAuth 2.0 Ich habe versucht zu empfangen.

Übrigens ist die Entwicklungsanwendung eine residente Anwendung, die die von dem für die Anwendung bestimmten E-Mail-Konto empfangenen E-Mails regelmäßig in einer Textdatei ausgibt. Die Authentifizierungsmethode lautet [ROPC-Fluss wird empfohlen, nicht zu verwenden](https :: //docs.microsoft.com/ja-jp/azure/active-directory/develop/v2-oauth-ropc) wird angenommen, daher ist das Folgende ein Implementierungsbeispiel.

Anmeldung zur Bewerbung

Ich habe auf das Tutorial für den allgemeinen Verarbeitungsablauf und dieses Verfahren verwiesen.

  1. Melden Sie sich beim Azure Active Directory-Verwaltungscenter mit dem Konto an, mit dem die App E-Mails empfängt, und klicken Sie auf [Azure Active Directory] - [App registrieren] - [Neue Registrierung]. image.png

  2. Geben Sie den Namen der App ein. Dieses Mal wird die App nur für ein bestimmtes Konto verwendet. Wählen Sie daher [Nur in diesem Organisationsverzeichnis enthaltene Konten]. Ich verwende den Umleitungs-URI nicht, berühren Sie ihn also nicht. Klicken Sie dann auf [Registrieren]. image.png

  3. Setzen Sie [Öffentlichen Clientfluss zulassen] auf [Ja] und klicken Sie auf [Speichern]. image.png

  4. Fügen Sie [IMAP.AccessAsUser.All] aus [Delegierte Berechtigungen] in [Microsoft Graph] unter [Berechtigungen hinzufügen] in [API-Berechtigungen] hinzu. Dieses Mal ist das angemeldete Konto auch ein Administrator. Klicken Sie einfach auf [Administrator-Zustimmung zu ~ erteilen]. image.png

Erstellen der zugrunde liegenden Anwendung

Ich habe Spring Boot 2.3.4 und Kotlin zur Vereinfachung verwendet. Fügen Sie nur Java Mail Sender (dh Spring-Boot-Starter-Mail) als Abhängigkeit vom Spring-Initialisierer hinzu und fügen Sie nach dem Erstellen eines Projekts die Microsoft-Authentifizierungsbibliothek für Java zu pom.xml hinzu.

pom.xml


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

Implementieren Sie CommandLineRunner und schreiben Sie den Prozess in die run-Methode.

@SpringBootApplication
class SampleMailApplication : CommandLineRunner {
  override fun run(vararg args: String?) {
    //Implementierung
  }
}

Zugriffstoken erhalten

Dieses Verfahren des oben genannten Tutorials ist nicht cool. Was ist "Open App.xaml", der Rest des C # -Artikels? .. .. Ich hatte keine andere Wahl, als es im Internet nachzuschlagen, und es begann mit dem folgenden Code zu arbeiten.

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

//Ausgelassen
override fun run(vararg args: String?) {
  //Geben Sie die Anwendungs-ID auf der Übersichtsseite der registrierten App an
  val applicationId = "..."
  // ...Geben Sie die Verzeichnis-ID auf der Übersichtsseite im Teil an
  val authEndpoint = "https://login.microsoftonline.com/.../oauth2/v2.0/authorize"
  //Geben Sie gemäß dem zu verwendenden Protokoll an
  val scope = setOf("https://outlook.office365.com/IMAP.AccessAsUser.All",
    "https://outlook.office365.com/SMTP.Send")
  //Geben Sie die E-Mail-Adresse des Kontos an
  val username = "..."
  //Geben Sie das Kontokennwort an
  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("Zugangstoken: ${result.accessToken()}")

eingehende Post

var props = Properties()
//OAuth 2 zur Authentifizierung.Verwenden Sie 0
props["mail.imaps.auth.mechanisms"] = "XOAUTH2"
var session: Session = Session.getInstance(props)
val store: Store = session.getStore("imaps")
//Verwenden Sie das Zugriffstoken als Passwort
store.connect("outlook.office365.com", 993, username, result.accessToken())
val folderInbox: Folder = store.getFolder("INBOX")
folderInbox.open(Folder.READ_ONLY)
folderInbox.messages.forEach { println("Gegenstand: ${it.subject}") }

Der erste Punkt ist mail.imaps.auth.mechanisms [Description](https://github.com/eclipse-ee4j/mail/blob/c3096cbeaf566f36998e96ff384378059f291ce8/mail/src/main/java/com/sun/mail/imap Laut /package.html#L405-L410) ist der Standardwert die gesamte unterstützte Authentifizierung mit Ausnahme von XOAUTH2, und Exchange Online verwendet die Basisauthentifizierung. Geben Sie daher XOAUTH2 an, um die OAuth 2.0-Authentifizierung zu aktivieren.

Sie können jetzt E-Mails mit OAuth 2.0-Authentifizierung empfangen, indem Sie einfach das Zugriffstoken anstelle des Kennworts angeben.

(Ergänzung) Mail senden

Vorerst möchte ich die OAuth 2.0-Authentifizierung für die Basisauthentifizierung von SMTP ausprobieren, die in Kürze abgeschafft wird. Weit entfernt von der OAuth 2.0-Authentifizierung, jedoch auch der Basisauthentifizierung

javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful

Ist es nicht![Automatisiertes SMTP im Postfach](https://docs.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/authenticated-client-smtp-submission#use-the -microsoft-365-admin-center-zum-Aktivieren oder Deaktivieren von SMTP-Authentifizierung für bestimmte Postfächer). .. ..

Auf der Seite heißt es: "Wenn Ihre Authentifizierungsrichtlinie die grundlegende SMTP-Authentifizierung deaktiviert, können Ihre Clients das SMTP-Authentifizierungsprotokoll nicht verwenden, selbst wenn Sie die in diesem Artikel beschriebenen Einstellungen aktivieren." Wenn Sie [Standardeinstellungen aktivieren] auf [Nein] setzen (https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/concept-fundamentals-security-defaults), wird die E-Mail erfolgreich gesendet. Wenn ich jedoch [Sicherheitsstandards aktivieren] auf [Ja] zurücksetze, tritt der Fehler nicht mehr auf. (Es ist nicht zu leugnen, dass etwas anderes manipuliert wurde ...)

Ich weiß nicht was es ist ...

Vorerst wird auch die erfolgreiche Übertragungslogik beschrieben.

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 = "Senden"
sendMessage.setText("Übertragungstest")

transport.sendMessage(sendMessage, sendMessage.allRecipients)

Obwohl die Übertragung selbst abgeschlossen wurde, wurde die endgültige Zustellung nicht mit "550 5.7.501 Dienst nicht verfügbar. Spam-Missbrauch aus IP-Bereich erkannt" abgeschlossen. Vom Ziel aus. Dies liegt daran, dass E-Mails aus der Domäne onmicrosoft.com als Spam gefiltert werden und ein Testversand aus Outlook das gleiche Ergebnis liefert. Ich halte dies daher nicht für ein logisches Problem.

Recommended Posts

Empfangen Sie E-Mails mit OAuth 2.0-Authentifizierung in Exchange Online
Oauth2-Authentifizierung mit Spring Cloud Gateway
SSO mit GitHub OAuth in der Spring Boot 1.5.x-Umgebung