title: How to get OAuth2 access token for EWS managed API in service/daemon application
body: <h1>Scenario</h1>
  
  <p>I have an Exchange Online environment and service/daemin (no interactive user) application on the Azure VM. Service uses EWS managed API to work with emails in the mailbox of <strong>any</strong> tenant user. Now EWS client uses Basic authentication that, according to Microsoft, will become unsupported in EWS to access Exchange Online.</p>
  
  <h1>Question/Issue</h1>
  
  <p>So, I need to find a way to get valid access token for service/daemon application to use with EWS managed API.</p>
  
  <h1>My findings</h1>
  
  <p>The following <a href="https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth" rel="noreferrer" title="Authenticate an EWS application by using OAuth">article</a> shows an example of using OAuth 2.0 with EWS managed API. This example works, but it uses interactive method of getting consent (sign-in form appears allowing user authenticate themselves and grant requested permission to application) that is not suitable for service/daemon app scenario, because there is no interactive user.</p>
  
  <p>For service/daemon application I need to use <code>client credential</code> authentication flow.</p>
  
  <h3>Registered application</h3>
  
  <p>Using admin account on <a href="https://aad.portal.azure.com" rel="noreferrer">https://aad.portal.azure.com</a> portal I registered application with Azure Active Directory. Added client secret for registered application.</p>
  
  <p>Aforementioned <a href="https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth" rel="noreferrer" title="Authenticate an EWS application by using OAuth">article</a> uses <code>https://outlook.office.com/EWS.AccessAsUser.All</code> as a <code>scope</code>. But I did not find permission with such a URL on the portal. I found only the following permissions under <code>Office 365 Exchange Online</code> > <code>Application permissions</code> > <code>Mail</code>:</p>
  
  <ol>
  <li><code>https://outlook.office365.com/Mail.Read</code> Allows the app to read mail in all mailboxes without a signed-in user</li>
  <li><code>https://outlook.office365.com/Mail.ReadWrite</code>  Allows the app to create, read, update, and delete mail in all mailboxes without a signed-in user. </li>
  </ol>
  
  <p>I added both of them and granted admin consent for all users.</p>
  
  <h3>Getting access token</h3>
  
  <p>For testing purposes and simplicity I did not use any auth libraries (ADAL, MSAL etc.). I used Postman to get access token, then set <code>token</code> variable in debug (see code snippet later in the post).</p>
  
  <p>I tried different endpoints to get acess token.</p>
  
  <ol>
  <li><strong>OAuth 2.0 token endpoint (v2)</strong></li>
  </ol>
  
  <pre><code>    POST: https://login.microsoftonline.com/&lt;TENANT_ID&gt;/oauth2/v2.0/token
          grant_type=client_credentials
          client_id=*** 
          client_secret=***
          scope=https://outlook.office.com/EWS.AccessAsUser.All
  </code></pre>
  
  <p>Sending this request produces the following error response:</p>
  
  <p><em>AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope <a href="https://outlook.office.com/EWS.AccessAsUser.All" rel="noreferrer">https://outlook.office.com/EWS.AccessAsUser.All</a> is not valid.</em></p>
  
  <p>I tried changing <code>scope</code> to <code>https://outlook.office.com/.default</code>. Access token was returned, but it appeared to be invalid for EWS. EWS client throws 401 error with the following value of <code>x-ms-diagnostics</code> response header:</p>
  
  <p><em>2000008;reason="The token contains no permissions, or permissions can not be understood.";error_category="invalid_grant"</em></p>
  
  <ol start="2">
  <li><strong>OAuth 2.0 token endpoint (v1)</strong></li>
  </ol>
  
  <pre><code>    POST: https://login.microsoftonline.com/&lt;TENANT_ID&gt;/oauth2/token
          grant_type=client_credentials
          client_id=*** 
          client_secret=***
          resource=https://outlook.office.com
  </code></pre>
  
  <p>Access token was returned, but also appeared to be invalid for EWS. EWS client throws 401 error with the same value of <code>x-ms-diagnostics</code> response header as described ealier in #1.</p>
  
  <h2>Use aquired access token with EWS managed API</h2>
  
  <p>Here is code sample that I used to test EWS client with access token acquired in Postman:</p>
  
  <pre class="lang-cs prettyprint-override"><code>var token = "...";
  var client = new ExchangeService
  {
      Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
      Credentials = new OAuthCredentials(token),
      ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,
                   "user@domain.onmicrosoft.com"),
  
  };
  var folder = Folder.Bind(client, WellKnownFolderName.SentItems);
  </code></pre>