Reputation: 1551
We recently migrated from on premise exchange to Microsoft 365 and I'm wanting to turn on 2FA for all users (Enable security defaults). However this disables SMTP authentication which we have been using for sending mail from a distribution group address. (Not achievable via EWS as it doesn't have a physical mailbox)
From what I can see, the only method would be to set up a SMTP relay or send via Microsoft Graph.
I've tried going down the Microsoft Graph route, and here's what I've got so far.
Create application in Azure Active Directory > App Registrations
Add Mail.Send
and User.Read.All
(Application, not delegated) API Permissions and have granted Admin Consent.
Request token using the following
{ "grant_type": "authorization_code", "client_id": "AzureApi.ClientId", "client_secret": "AzureApi.ClientSecret", "code": "insert auth code", "redirect_uri": "insert redirect URL" }
to get the bearer tokenOnce I have the token, Now I perform a request to send some mail
fromAddress
is the email address of the user that requested the token, however when I try to send from a different address it gives this error {"error":{"code":"ErrorAccessDenied","message":"Access is denied. Check credentials and try again."}}
SendAs
permission to the token user for the mailbox I was trying to send as, but this didn't make any difference. Regardless - I want to be able to send as any user without delegating permissions to each mailbox.Glad of any help. Thanks!!
Upvotes: 10
Views: 40069
Reputation: 31
To restrict the App Registration to only be able to send as specific mailboxes, you need to add an Application Access Policy in Exchange Online.
Here's my steps to set up the App Registration to suit the application and limit its access to the specific mailbox(es):
Create an App Registration for your sending application. Name it to suit.
Grant the App Registration permissions to send email using the method that suits the application.
a. Click on "API permissions"
b. Click on "+ Add a permission"
c. Click on "APIs my organization uses"
d. Search for "Office", then select "Office 365 Exchange Online"
e. Click on "Application Permissions"
f. Find and add the permission for the method to be used to send email
EWS "full_access_as_app"
SMTP "SMTP.SendAsApp"
Graph "Mail.Send"
A Global Admin will need to grant consent once the permissions have been added.
Create a Mail-enabled Security Group with the mailboxes the application is to be permitted to send as members.
Create an Application Access Policy in Exchange Online to restrict the App Registration to the mailboxes in the Mail-enabled Security Group.
New-ApplicationAccessPolicy -AppId "" -PolicyScopeGroupId "Mail-enabled Security Group name" -AccessRight RestrictAccess
Create a secret key for App Registration
The application will need the TenantID, AppID and the Secret key to request an OAUTH token from Azure with the appropriate rights.
Upvotes: 0
Reputation: 64
I could test sending emails from an application (with any user) with postman.
First get a token:
POST https://login.microsoftonline.com/<tenant ID>/oauth2/v2.0/token?grant_type=client_credentials
Key Value
client_id <client ID>
scope https://graph.microsoft.com/.default
client_secret <secret>
grant_type client_credentials
Response:
{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 3599,
"access_token": <token>
}
Send email:
POST https://graph.microsoft.com/v1.0/users/[email protected]/sendMail
Authorization Bearer Token: <Bearer token>
Body
{
"message" : {
"subject": "test email with any user",
"body" : {
"contentType": "html",
"content": "sending from postman"
},
"toRecipients": [
{
"emailAddress" : {
"address" : <to email address>
}
}
] ,
"ccRecipients": [
{
"emailAddress" : {
"address" : <cc email address>
}
}
] ,
"bccRecipients": [
{
"emailAddress" : {
"address" : <bcc email address>
}
}
]
}
}
Response:
202 Accepted
Upvotes: 3
Reputation: 1771
The behavior you are getting is expected because you are using delegated permissions - authorization code flow. This flow will not allow your app to send email as any user except the user that is signed in/"requested the token".
In your case you can add the permissions as application permissions and then use Client Credentials flow with either secret or certificate(more secure). Your token request will look like the Get Access Token Section. Note that this means two things:
Upvotes: 12