Configure OAuth authentication between Exchange and Exchange Online organizations

Applies to: Exchange Server 2013

The Hybrid Configuration wizard automatically configures OAuth authentication between Exchange 2013 and Exchange Online organizations. If your Exchange 2013 organization contains Exchange 2010 or Exchange 2007 servers, the Hybrid Configuration wizard doesn't configure OAuth authentication between the on-premises and online Exchange organizations. These deployments continue to use the federation trust process by default. However, certain Exchange 2013 features are only fully available across your organization by using the new Exchange OAuth authentication protocol.

The new Exchange OAuth authentication process currently enables the following Exchange features:

  • Message Records Management (MRM)
  • Exchange In-place eDiscovery
  • Exchange In-place Archiving

We recommend that all mixed Exchange 2013 organizations configure Exchange OAuth authentication after running the Hybrid Configuration Wizard.

Important

  • If your on-premises organization is running only Exchange 2013 servers with Cumulative Update 5 or later installed, run the Hybrid Deployment Wizard instead of performing the steps in this topic.

  • This feature of Exchange Server 2013 isn't fully compatible with Office 365 operated by 21Vianet in China and some feature limitations may apply. For more information, see Office 365 operated by 21Vianet.

What do you need to know before you begin?

Tip

Having problems? Ask for help in the Exchange forums. Visit the forums at Exchange Server.

How do you configure OAuth authentication between your on-premises Exchange and Exchange Online organizations?

Step 1: Create the authorization server objects for your Exchange Online organization

For this procedure, you have to specify a verified domain for your Exchange Online organization. It should be the same domain used as the primary SMTP domain used for the cloud-based email accounts. This domain is referred to as <your verified domain> in the following procedure.

Run the following command in the Exchange Management Shell (Exchange PowerShell) in your on-premises Exchange organization:

New-AuthServer -Name "WindowsAzureACS" -AuthMetadataUrl "https://accounts.accesscontrol.windows.net/<your tenant coexistence domain>/metadata/json/1"
New-AuthServer -Name "evoSTS" -Type AzureAD -AuthMetadataUrl "https://login.windows.net/<your tenant coexistence domain>/federationmetadata/2007-06/federationmetadata.xml"

Note

In GCC High or DoD, you need to use the following commands instead:

New-AuthServer -Name "WindowsAzureACS" -AuthMetadataUrl "https://login.microsoftonline.us/<your tenant coexistence domain>/metadata/json/1"
New-AuthServer -Name "evoSTS" -Type AzureAD -AuthMetadataUrl "https://login.microsoftonline.us/<your tenant coexistence domain>/federationmetadata/2007-06/federationmetadata.xml"

Note

The Tenant coexistence domain is of the form contoso.mail.onmicrosoft.com

Step 2: Enable the partner application for your Exchange Online organization

Run the following command in the Exchange PowerShell in your on-premises Exchange organization.

Get-PartnerApplication |  ?{$_.ApplicationIdentifier -eq "00000002-0000-0ff1-ce00-000000000000" -and $_.Realm -eq ""} | Set-PartnerApplication -Enabled $true

Step 3: Export the on-premises authorization certificate

In this step, you have to run a PowerShell script on the Exchange server directly to export the on-premises authorization certificate, which is then imported to your Exchange Online organization in the next step.

  1. Save the following text to a PowerShell script file named, for example, ExportAuthCert.ps1.

    $thumbprint = (Get-AuthConfig).CurrentCertificateThumbprint
    if((test-path $env:SYSTEMDRIVE\OAuthConfig) -eq $false)
    {
       md $env:SYSTEMDRIVE\OAuthConfig
    }
    cd $env:SYSTEMDRIVE\OAuthConfig
    $oAuthCert = (dir Cert:\LocalMachine\My) | where {$_.Thumbprint -match $thumbprint}
    $certType = [System.Security.Cryptography.X509Certificates.X509ContentType]::Cert
    $certBytes = $oAuthCert.Export($certType)
    $CertFile = "$env:SYSTEMDRIVE\OAuthConfig\OAuthCert.cer"
    [System.IO.File]::WriteAllBytes($CertFile, $certBytes)
    
  2. In Exchange PowerShell in your on-premises Exchange organization, run the PowerShell script that you created in the previous step. For example:

    .\ExportAuthCert.ps1
    

Step 4: Upload the on-premises authorization certificate to Microsoft Entra Access Control Service (ACS)

Next, use the Microsoft Graph PowerShell to upload the on-premises authorization certificate that you exported in the previous step to Microsoft Entra Access Control Services (ACS). If you don't have the module installed, open a Windows PowerShell window as an administrator and run the following command:

Install-Module -Name Microsoft.Graph.Applications

Complete the following steps after the Microsoft Graph PowerShell is installed.

  1. Open a Windows PowerShell workspace that has the Microsoft Graph cmdlets installed. All commands in this step will be run using the Windows PowerShell connected to Microsoft Graph console.

  2. Save the following text to a PowerShell script file named, for example, UploadAuthCert.ps1.

     Connect-MgGraph -Scopes Application.ReadWrite.All
    
     $CertFile = "$env:SYSTEMDRIVE\OAuthConfig\OAuthCert.cer"
     $objFSO = New-Object -ComObject Scripting.FileSystemObject
     $CertFile = $objFSO.GetAbsolutePathName($CertFile)
     $cer = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($CertFile)
     $binCert = $cer.GetRawCertData()
     $credValue = [System.Convert]::ToBase64String($binCert)
     $ServiceName = "00000002-0000-0ff1-ce00-000000000000"
     $p = Get-MgServicePrincipal -Filter "AppId eq '$ServiceName'"
     $params = @{
     	keyCredentials = @{
     		type = "AsymmetricX509Cert"
     		usage = "Verify"
     		key = $credValue
     	}
     }
     Update-MgServicePrincipal -ServicePrincipalId $p.Id -BodyParameter $params
    
  3. Run the PowerShell script that you created in the previous step. For example:

    .\UploadAuthCert.ps1
    
  4. After you start the script, a credentials dialog box is displayed. Enter the credentials for the tenant administrator account in your Microsoft Online Microsoft Entra organization. After running the script, leave the Windows PowerShell connected to Microsoft Graph session open. You will use this to run a PowerShell script in the next step.

Step 5: Register all hostname authorities for your internal and external on-premises Exchange HTTP endpoints with Microsoft Entra ID

You need to run the script in this step for each publicly-accessible endpoint in your on-premises Exchange organization, including Internal and External URLs for Hybrid Modern Authentication). For example, if Exchange is externally available at https://mail.contoso.com/ews/exchange.asmx, use the service principal name https://mail.contoso.com. There isn't a limit for registering additional external hostname authorities.

To confirm the Exchange endpoints in your on-premises organization, run the following commands in the Exchange Management Shell:

Get-MapiVirtualDirectory | FL server,*url*
Get-WebServicesVirtualDirectory | FL server,*url*
Get-OABVirtualDirectory | FL server,*url*

Note

The following script requires that the Windows PowerShell connected to Microsoft Graph is connected to your Microsoft 365 organization, as explained in step 4 in the previous section.

  1. Save the following text to a PowerShell script file named, for example, RegisterEndpoints.ps1. This example uses a contoso.com. Replace https://mail.contoso.com/ and https://autodiscover.contoso.com/ with the appropriate hostname authority for your on-premises Exchange organization.

     $ServiceName = "00000002-0000-0ff1-ce00-000000000000";
     $x = Get-MgServicePrincipal -Filter "AppId eq '$ServiceName'"
     $ServicePrincipalUpdate =@(
        "https://mail.contoso.com/","https://autodiscover.contoso.com/"
     )
     Update-MgServicePrincipal -ServicePrincipalId $x.Id -ServicePrincipalNames $ServicePrincipalUpdate
    
  2. In Windows PowerShell connected to Microsoft Graph, run the Windows PowerShell script that you created in the previous step. For example:

    .\RegisterEndpoints.ps1
    
  3. To verify that all the records were added, run the following command in Windows PowerShell connected to Microsoft Graph and look for https://namespace entries in the results.

    Get-MgServicePrincipal -Filter "AppId eq '$ServiceName'" | select -ExpandProperty ServicePrincipalNames
    

Step 6: Create an IntraOrganizationConnector from your on-premises organization to Microsoft 365 or Office 365

You must define a target address for your mailboxes that are hosted in Exchange Online. This target address is created automatically when your Microsoft 365 or Office 365 organization is created. For example, if your organization's domain hosted in the Microsoft 365 or Office 365 organization is "contoso.com", your target service address would be "contoso.mail.onmicrosoft.com".

Using Exchange PowerShell, run the following cmdlet in your on-premises organization:

$ServiceDomain = Get-AcceptedDomain | where {$_.DomainName -like "*.mail.onmicrosoft.com"} | select -ExpandProperty Name
New-IntraOrganizationConnector -name ExchangeHybridOnPremisesToOnline -DiscoveryEndpoint https://outlook.office365.com/autodiscover/autodiscover.svc -TargetAddressDomains $ServiceDomain

Step 7: Create an IntraOrganizationConnector from your Microsoft 365 or Office 365 organization to your on-premises Exchange organization

You must define a target address for your mailboxes that are hosted in your on-premises organization. If your organization's primary SMTP address is in "contoso.com", the target addresses would be in "contoso.com".

You must also define the external Autodiscover endpoint for your on-premises organization. If your company is "contoso.com", the Autodiscover endpoint is usually one of the following values:

  • https://autodiscover.<your primary SMTP domain>/autodiscover/autodiscover.svc
  • https://<your primary SMTP domain>/autodiscover/autodiscover.svc>

Note

You can use the Get-IntraOrganizationConfiguration cmdlet in both your on-premises and Microsoft 365 or Office 365 tenants to determine the endpoint values needed by New-IntraOrganizationConnector cmdlet.

After you connect to Exchange Online PowerShell, replace <your on-premises Autodiscover endpoint> and <your on-premises SMTP domain> with your values and run the following command:

New-IntraOrganizationConnector -name ExchangeHybridOnlineToOnPremises -DiscoveryEndpoint <your on-premises Autodiscover endpoint> -TargetAddressDomains <your on-premises SMTP domain>

Step 8: Configure an AvailabilityAddressSpace for any pre-Exchange 2013 SP1 servers

When you configure a hybrid deployment in older Exchange organizations, you need at least one Exchange 2013 server that's running Exchange 2013 SP1 or later. The Exchange 2013 server requires the Client Access and Mailbox server roles. The Exchange 2013 server coordinates communications between your existing Exchange on-premises organization and the Exchange Online organization. We highly recommend installing more than one Exchange 2013 server in your on-premises organization to help increase reliability and availability of hybrid deployment features.

In Exchange 2013 organizations with Exchange 2010 or Exchange 2007, we recommended that all Internet-facing frontend servers are Exchange 2013 Client Access servers running SP1 or later. All Exchange Web Services (EWS) requests must go through an Exchange 2013 Client Access server. This requirement includes requests from Microsoft 365 to your on-premises Exchange organization, and requests from your on-premises Exchange organization to Microsoft 365. It's important that you have enough Exchange 2013 Client Access servers to handle the processing load and to provide connection redundancy. The number of Client Access servers you need depends on the average amount of EWS requests, and varies by organization.

Before you complete the following step, make sure:

  • The frontend hybrid servers are Exchange 2013 SP1 or greater.
  • You have a unique external EWS URL for the Exchange 2013 server(s). The Microsoft 365 or Office 365 organization must connect to these servers in order for cloud-based requests for hybrid features to work correctly.
  • The servers have both the Mailbox and Client Access server roles
  • Any existing Exchange 2010/2007 Mailbox and Client Access servers have the latest Cumulative Update (CU) or Service Pack (SP) applied.

Note

Existing Exchange 2010/2007 Mailbox servers can continue to use Exchange 2010/2007 Client Access servers for frontend servers for non-hybrid feature connections. Only hybrid deployment feature requests from the Microsoft 365 or Office 365 organization need to connect to Exchange 2013 servers.

An AvailabilityAddressSpace must be configured on pre-Exchange 2013 Client Access servers that points to the Exchange Web Services endpoint of your on-premises Exchange 2013 SP1 Client Access server(s). This endpoint is the same endpoint as previously outlined in Step 5 or can be determined by running the following cmdlet on your on-premises Exchange 2013 SP1 Client Access server:

Get-WebServicesVirtualDirectory | Format-List AdminDisplayVersion,ExternalUrl

Note

If virtual directory information is returned from multiple servers, make sure you use the endpoint returned for an Exchange 2013 SP1 Client Access server. It will display 15.0 (Build 847.32) or higher for the AdminDisplayVersion parameter.

To configure the AvailabilityAddressSpace, use Exchange PowerShell and run the following cmdlet in your on-premises organization:

Add-AvailabilityAddressSpace -AccessMethod InternalProxy -ProxyUrl <your on-premises External Web Services URL> -ForestName <your Microsoft 365 or Office 365 service target address> -UseServiceAccount $True

How do you know this worked?

You can verify that the OAuth configuration is correct by using the Test-OAuthConnectivity cmdlet. This cmdlet verifies that the on-premises Exchange and Exchange Online endpoints can successfully authenticate requests from each other.

To verify that your on-premises Exchange organization can successfully connect to Exchange Online, run the following command in Exchange PowerShell in your on-premises organization:

Test-OAuthConnectivity -Service EWS -TargetUri https://outlook.office365.com/ews/exchange.asmx -Mailbox <On-Premises Mailbox> -Verbose | Format-List

To verify that your Exchange Online organization can successfully connect to your on-premises Exchange organization, connect to Exchange Online PowerShell and run the following command:

Test-OAuthConnectivity -Service EWS -TargetUri <external hostname authority of your Exchange On-Premises deployment>/metadata/json/1 -Mailbox <Exchange Online Mailbox> -Verbose | Format-List

So, as an example,

Test-OAuthConnectivity -Service EWS -TargetUri `https://mail.contoso.com/metadata/json/1` -Mailbox ExchangeOnlineBox1 -Verbose | Format-List

Important

You can ignore the "The SMTP address has no mailbox associated with it." error. It's only important that the ResultTask parameter returns a value of Success. For example, the last section of the test output should read:

ResultType: Success Identity: Microsoft.Exchange.Security.OAuth.ValidationResultNodeId IsValid: True ObjectState: New

Tip

Having problems? Ask for help in the Exchange forums. Visit the forums at Exchange Server.