Sending email with OAuth authentication to Office 365 using MgGraph

Copper Contributor

Hi all,

 

I'm trying to send emails using MgGraph and Modern Authentication and somehow this fails.

The sender receives an auto-respond from Exchange saying;

 

Diagnostic information for administrators:

 

Generating server: AS8PR08MB9314.eurprd08.prod.outlook.com

<from address>

Remote server returned '550 5.7.708 Service unavailable. Access denied, traffic not accepted from this IP. For more information please go to http||go.microsoft.com/fwlink/?LinkId=526653 AS(7230) [AS1PR08MB7586.eurprd08.prod.outlook.com 2023-05-14T09:19:00.773Z 08DB542B00E328F8]'

 

Original message headers:

 

Received: from AS8PR08MB9314.eurprd08.prod.outlook.com([fe80::4599:1fd:9e8d:8974]) by AS8PR08MB9314.eurprd08.prod.outlook.com ([fe80::4599:1fd:9e8d:8974%6]) with mapi id 15.20.6387.029; Sun, 14 May 2023 09:19:00 +0000

MIME-Version: 1.0

Content-Type: text/plain

Date: Sun, 14 May 2023 09:19:00 +0000

Message-ID: [email address removed for privacy reasons] Subject: OAuth Mail Sent from PowerShell via App

 

Let me explain what I'm doing;

I have a script that is using Graph API to send the email. This script is authenticating with a certificate (self-signed on my laptop and added to the App Registration earlier) on an AD Application that has Graph API Mail.Send permissions.

The Graph POST is successful, but Exchange immediately sends back the above NDR.

 

Install-Module MSAL.PS
Import-Module MSAL.PS

$appName = "MailSendingTestApp"
$appRegistration = @{
   TenantId = "xxx.onmicrosoft.com"
   ClientId = "<app-id>"
   ClientCertificate = (Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Subject -eq ('CN={0}' -f $appName)})
}

$msalToken = Get-MsalToken @appRegistration -ForceRefresh -AzureCloudInstance 1

$fromEmailAddress = "email address removed for privacy reasons"
$requestBody = @{
   "message" = [PSCustomObject]@{
        "subject" = "OAuth Mail Test"
        "body" = [PSCustomObject]@{
            "contentType" = "Text"
            "content" = "Hello this is a test"
        }
        "toRecipients" = @(
            [PSCustomObject]@{
                "emailAddress" = [PSCustomObject]@{
                      "address" = "email address removed for privacy reasons"
                 }
             }
        )
        }
        "saveToSentItems" = "true"
}

$request = @{
        "Headers" = @{Authorization = $msalToken.CreateAuthorizationHeader() }
        "Method" = "Post"
        "Uri" = "https || graph.microsoft.com/v1.0/users/$fromEmailAddress/sendMail "
        "Body" = $requestBody | ConvertTo-Json -Depth 5
        "ContentType" = "application/json"
}

Invoke-RestMethod @request

 

 

 

Googling led me to a post that links to a MS article that says; "This error can happen when you are trying out a Microsoft 365 trial tenant. If you receive this error before you can purchase licenses, contact support to request an exception for the low reputation IP address until you're able to purchase licenses."

My tenant is licensed with Microsoft 365 E5 Developer (part of the Visual Studio benefit that comes with our partner account). 

 

What could be going wrong here? Do I need to contact Microsoft here or start pulling my wallet?

 

Hope someone can help.

Cheers!

4 Replies

@chanlerone 

Try to check SPF Record and add MgGraph to it, and also check connection filter policy if enabled

 

 


If I have answered your question, please mark your post as Solved


If you like my response, please give it a Like :smile:


Appreciate your Kudos! Proud to contribute! :)

 

 

What do you mean with SPF record of MgGraph? AFAIK there is only Exchange Online's record we need to add [include:spf.protection.outlook.com] according to: https://learn.microsoft.com/en-us/microsoft-365/security/office-365-security/email-authentication-sp...

And which connection filter do you refer to?

Furthermore, the rejection comes from O365 servers: AS8PR08MB9314.eurprd08.prod.outlook.com
What I would expect is that I am posting a request to the Graph API that is accepted. The API's SMTP services will go ahead and try to send the email to Exchange Online, which in turn would need to deliver this to the intended recipient.
If Exchange Online already reject the email that is being delivered by the API, then Graph's servers would not be trusted by Exchange Online. How can I fix this?
Thanks everyone for helping out, but I just confirmed this to be a problem related to having a Developer license.
As soon as I try this on a production tenant with licenses it immediately works and mails are received by the intended recipient.
It seems Microsoft has some kind of protection to prevent misuse of trial and developer accounts.
A good thing, but not helpful if you want to test something conceptually before putting it in production.