Send email on behalf of a service account using Office Graph API

Frank Chen
4 min readJul 14, 2016

--

Update: Please reference to How to allow AAD App with Application Permissions to access specific email boxes for leveraging EXO Application Access Policy to limit the Application Permission to access specific email accounts.

As O365 is getting popular, a lot of custom solutions are built to communicate each of components inside O365. Like SharePoint online, Exchange online and Skype for Business. Recently I was asked by my customers to build a custom solution to provisioning site collection and site on SPO and send out notification to end user once provisioning process is completed. Since my customer was on O365 and they already integrated their on premise AD with Azure AD, each end user was able to access SPO, Exchange and Skype for Business through their own domain account. As traditional business requirement, the most of end-users would like to see a nice notification email after their provisioning request was processed. The question we were dealing with was how to send out a notification email to end users from our provisioning process. This seems a simple question when we are developing something at on premise environment because we can easily use SmtpClient to send out a email as long as we have a valid Smtp Server. I believe the most of companies do have a valid Smtp server for their day-to-day email work. However it might not be a case for users who are on O365. Even though you can have your Smtp and Pop3 servers available from POP and IMAP settings for Outlook Office 365 for business, you might want to use a app-only account to send out email on behalf of a service account.

Before I start to explain my notification solution, let me spend a little bit time to explain our provisioning process. The existing provisioning process itself was built on top of Office PnP Partner and Pack. It was actually hosted on Windows Azure Web App and leveraged App-Only authentication to secure the access to SharePoint online content and Web APIs themselves which we provided. The whole solution is using SPA + Web API model. So for our notification function, we decided to use the same approach as SPO to communicate Outlook online service to send email on behalf of a service account.

As I mentioned before, our SPA+Web API solution relied on Azure AD for authentication. A Azure AD App was created to secure SPA and Web API. In order to allow our Web API to request a app-only token to communicate to O365, we also needed to configure our Azure AD App to make sure it’s able to delegate permission as a app access. You can reference Build service and daemon apps in Office 365 for the detail configuration. I will outline some of important steps as below:

  • Create a Azure AD application through https://manage.windowsazure.com portal site.
  • For the permission of your Azure AD Application, grant “Send mail as any user” under “Application Permissions” dropdown list. it allows your app-only authentication to have permission to send email on behalf of someone else.
  • Create a X.509 certificate. For testing purpose a self-issued certificate is accepted by Azure AD application. The key point here is your certificate needs 2048 key length.
makecert -r -pe -n “CN=AppOnlyCert” -b 7/1/2016 -e 7/1/2020 -ss my -len 2048
  • Get Base64 encoded certificate value and thumbprint from your self-issued certificate by running the following PS code. (Reference to GetCertificate.ps1)
  • Go to your Azure AD application and download manifest file. the menu is located under bottom menu bar.
  • Open your downloaded manifest file which should be a JSON file and replace “keyCredentials” section. (reference keyCredentials.json)
  • Save your change and upload back to your Azure AD application. NOTE: You need Tenant Admin permission to be able to perform this action. Even though you are co-admin, without tenant admin permission, you will get exception like below:

Once you have your Azure AD application configured, you can reference the following code to send email through Outlook online REST API. The key point here is you are able to delegate to other accounts by specifying the delegated account’s UPN in REST API URL after you request app-only token

a few comments regarding above sample code:

  • For the send email API URL “https://outlook.office.com/api/v2.0/users/service@contoso.com/sendmail", use an on-behalf account’s UPN.
  • For “message” anonymous object type, you can reference to here for detail definition.
  • For certificate password, you can leverage Azure Key Vault to protect your key if you are going to deploy to Microsoft Azure.
  • For certificate file location, you can implement code to read from your certificate store which can be feasible on Azure Web App as well.
  • The key point here for AccquireTokenAsync() method working is to use one of overloaded methods which accepts X509Certificate2 as one of parameter.
  • Once you have token requested from Azure AD, you are able to attach that token to REST API call for Outlook Online service.

For a completed sample, please reference to AppOnlySendEmailSample on the Github.

I hope you like it and let me know if you have any comments.

--

--

Responses (1)