Disabling Legacy Authentication in Exchange Server 2019
Published Jun 21 2019 08:53 AM 58.2K Views

We are happy to announce our work to allow you to disable legacy authentication is available to you with the second cumulative update (CU2) for Exchange 2019. This provides an important step down the path of removing legacy authentication mechanisms from Exchange Hybrid deployments.

This feature is very similar to the functionality offered in Office 365 for Disabling Basic authentication.

Why is this feature important?

As you probably know, legacy authentication methods are less secure, are vulnerable to interception and are susceptible to brute-force and password spray attacks. If your organization has no legacy email clients or doesn’t want to allow legacy email clients, you can use these new Authentication Policies in your Exchange Hybrid environment to disable legacy authentication requests. This ensures only those clients that support Hybrid Modern Authentication can connect to Exchange Server.

What are ‘legacy’ authentication methods?

Exchange Server has been around for 23 years, so we’ve seen a lot of change over that time. We’ve had to support multiple authentication methods over this time, to keep in sync with clients and to allow simple migration. The following legacy authentication methods have historically been used to access Exchange servers, and it’s the removal of these were are interested in for the purposes of this feature and post.

  • Basic authentication
  • Digest authentication
  • Windows authentication (NTLM and Kerberos)

So what do you need to do to configure this new feature?

Pre-requisites

  1. Verify that Hybrid Modern Authentication is enabled and successfully working in your Exchange Hybrid environment.
  2. Verify that all of your email clients and apps support Modern Authentication. Clients that currently support Hybrid Modern Auth are listed below. It’s also really important to keep your clients up to date – no only does that ensure they get fixes for any issues we find, but it means they get the latest features and capabilities too.
  • Outlook 2013 or later (Outlook 2013 requires a registry key change)
  • Outlook 2016 for Mac or later
  • Outlook for iOS and Android
  • Mail for iOS 11.3.1 or later

Authentication Policies

You block legacy authentication in Exchange hybrid environments by creating authentication policies. Authentication policies define the client protocols where legacy authentication is blocked (all protocols or specific protocols, although we typically recommend blocking legacy authentication for all protocols).

After you create authentication policies, you assign them to users. Assigning a policy to users blocks their legacy authentication requests for the specified protocols. Note that for the policy to take effect, mailboxes must be on an Exchange 2019 CU2 server and connection to the mailbox cannot come through an older version of Exchange.

You manage all aspects of authentication policies in the Exchange Management Shell.

Supported Protocols and Services

The protocols and services in Exchange that you can block legacy authentication for are described in the following table.

Protocol or service

Description

Parameter name

Exchange Active Sync (EAS)

Used by some email clients on mobile devices.

BlockLegacyAuthActiveSync

Autodiscover

Used by Outlook and EAS clients to find and connect to mailboxes in Exchange

BlockLegacyAuthAutodiscover

IMAP

Used by IMAP email clients.

BlockLegacyAuthImap

MAPI over HTTP (MAPI/HTTP)

Used by Outlook 2013 and later.

BlockLegacyAuthMapi

Offline Address Book (OAB)

A copy of address list collections that are downloaded and used by Outlook.

BlockLegacyAuthOfflineAddressBook

POP3

Used by POP email clients.

BlockLegacyAuthPop

Outlook Anywhere (RPC over HTTP)

Used by Outlook 2016 and earlier.

BlockLegacyAuthRpc

Exchange Web Services (EWS)

A programming interface that’s used by Outlook, Outlook for Mac, and third-party apps.

BlockLegacyAuthWebServices

Typically, when you block legacy authentication for a user, we recommend that you block legacy authentication for all protocols. However, you can use the BlockLegacyAuth* parameters (switches) on the New-AuthenticationPolicy and Set-AuthenticationPolicy cmdlets to selectively allow or block legacy authentication for specific protocols.

Step 1: Create the Authentication Policy

To create a policy that blocks legacy authentication for the specified client protocol, use the New-AuthenticationPolicy cmdlet.

This example creates an authentication policy named “Block Legacy Auth” to block legacy authentication for all client protocols in Exchange 2019 (the recommended configuration).

 

New-AuthenticationPolicy -Name "Block Legacy Auth" -BlockLegacyAuthActiveSync -BlockLegacyAuthAutodiscover -BlockLegacyAuthImap -BlockLegacyAuthMapi -BlockLegacyAuthOfflineAddressBook -BlockLegacyAuthPop -BlockLegacyAuthRpc -BlockLegacyAuthWebServices

Step 2: Assign the authentication policy to users

The methods that you can use to assign authentication policies to users are:

Individual user accounts:

This example assigns the policy named Block Legacy Auth to the user account laura@contoso.com.

Set-User -Identity laura@contoso.com -AuthenticationPolicy "Block Legacy Auth"

Filter user accounts by attributes: This method requires that the user accounts all share a unique filterable attribute (for example, Title or Department) that you can use to identify the users.

This example assigns the policy named Block Legacy Auth to all user accounts whose Title attribute contains the value “Sales Associate”.

 

$SalesUsers = Get-User -ResultSize unlimited -Filter {(RecipientType -eq 'UserMailbox') -and (Title -like '*Sales Associate*')}
$Sales = $SalesUsers.SamAccountName
$Sales | foreach {Set-User -Identity $_ -AuthenticationPolicy "Block Legacy Auth"}

Use a list of specific user accounts: This method requires a text file to identify the user accounts. Values that don’t contain spaces (for example, the user principal name or UPN) work best. The text file must contain one user account on each line like this:

 

akol@contoso.com
tjohnston@contoso.com
kakers@contoso.com

The syntax uses two commands (one to identify the user accounts, and the other to apply the policy to those users).

This example assigns the policy named Block Legacy Auth to the user accounts specified in the C:\My Documents\BlockLegacyAuth.txt file

 

$BLA = Get-Content "C:\My Documents\BlockLegacyAuth.txt"
$BLA | foreach {Set-User -Identity $_ -AuthenticationPolicy "Block Legacy Auth"}

Configure the default authentication policy

The default authentication policy is assigned to all users who don’t already have a specific policy assigned to them (a directly assigned policy takes precedence).

You can configure the default authentication policy for the organization, using the

Set-OrganizationConfig cmdlet.

This example below configures the authentication policy named “Block Legacy Auth” as the default policy.

 

Set-OrganizationConfig -DefaultAuthenticationPolicy "Block Legacy Auth"

How does this feature work in practice?

The diagrams below illustrate how this feature works once a policy has been created and assigned.

 

 

Hybrid Modern Auth FlowHybrid Modern Auth Flow

 

Legacy Auth FlowLegacy Auth Flow

How do I view authentication policies?

To view a summary list of the names of all existing authentication policies, run the following command:

 

Get-AuthenticationPolicy | Format-Table -Auto Name

To view detailed information about a specific authentication policy, use this syntax:

Get-AuthenticationPolicy -Identity "Block Legacy Auth"

How do I remove authentication policies?

To remove the policy run the following command. Please note that it would take around one hour for policy to be removed after the command is executed.

To remove the policy for a particular user , say userA, use the following command.

 

Set-User userA -AuthenticationPolicy $null

To remove the policy for the Organization level , use the following command.

 

Set-OrganizationConfig -DefaultAuthenticationPolicy $null

Summary

You now have a way to block legacy authentication mechanisms for users in your Organisation so that they all can use Modern Authenticaion . We would love to hear your feedback. Please do leave us comments below.

Thank you,

The Exchange Team

 

44 Comments
Brass Contributor

We‘d love to see this showing up for all Exchange releases that support Hybrid Modern Auth today - as companies may have reasons not to migrate to 2019 yet due to their Cloud strategy

Any chance we could see this showing up in the 2016 space as well? Thanks guys!

Copper Contributor
When will we see Modern Authentication on Exchange Server 2019 without cloud (AAD) prerequisites?
Brass Contributor

@Han Valk: The answer is in the Blog Article about the release of CU2 ;)

Copper Contributor

I am curious why kerberos is listed as a legacy authentication mechanism, especially why it is deemed unsafe. Are there security considerations concerning kerberos? Has the protocol been hacked or are there client and/or server specific vulnerabilities?

 

Since kerberos is used almost exclusively in an AD domain any vulnerabilities would be of great importance and interest to anybody using Windows in a work environment.

 

Sincerly

Markus

 

@Martin_Aigner  - 2019 only for this feature. 

@MarkusTUD - Kerberos will still be used between servers, but for clients it's much harder to enforce things like MFA and it can't be used from outside the network firewall/edge. So we'd like to get clients off it and onto something better. 

Copper Contributor

I have a question - why can't we just remove all the other authentication protocols (Basic, NTLM, Windows Integrated etc.) and leave only oAuth from, say from MAPI virtual directory and only enforce HMA for Outlook connection ? 

Because setup, CU's and our cmdlets will keep adding them back - we need some of those for server to server auth. 

Copper Contributor

Does server to server communication use Basic and NTLM authentication as well ?

Not generally, though MRS based mailbox moves use NTLM. Turning off Basic using the cmdlets if fine imho - but turning off IWA is not. 

Copper Contributor

@Greg Taylor - EXCHANGE  - Thank you ! 

Brass Contributor

This is great news, going to look at implementing this.

 

Greg, when you say Exchange continues to leverage NTLM in some places, if one was to implement NTLM blocking using GPO (Network security: Restrict NTLM: NTLM authentication in this domain) this would break Exchange if we have multiple Exchange servers? The goal being to enforce usage of Kerberos instead.

@Mirza Dedic - it wouldn't be supported, and some things might break (MRS based moves to O365 use NTLM, just one example). You can't do Kerberos from outside the firewall either, so if you use Outlook Anywhere, you can't use Kerb for users outside the firewall. 

Brass Contributor

Hey @Greg Taylor - EXCHANGE , great article. 

When we will see ModernAuth 100% on-premise without hybrid modern authentication requirement?

@Jonathan  - never, we decided to shelve that plan and announced it here - https://techcommunity.microsoft.com/t5/exchange-team-blog/released-june-2019-quarterly-exchange-upda... . Sorry. 

Brass Contributor

@Greg Taylor - EXCHANGE Can we use this feature by adding some Exchange 2019 servers to our Exchange 2016 environment and then route all incoming traffic like EWS from the internet to these 2019 server to be able to use modern auth and and block legacy auth at the same time?

@Hap  Authentication Policies only apply to mailboxes homed on 2019 as the blog says: "Note that for the policy to take effect, mailboxes must be on an Exchange 2019 CU2 server"

Copper Contributor

@Greg Taylor - EXCHANGE when I set the policy at the organization level things stop working. Once I execute 

 

Set-OrganizationConfig -DefaultAuthenticationPolicy "Block Legacy Auth"

windows/dialog boxes will start flashing on half of the outlook clients. It flashes fast and I can't tell if there is any content. Also, half the phones will stop working. When I set the authentication policy back to null everything starts working again but legacy auth is still enabled.

 

If I set the authentication policy at the user level things work as you would expect. HMA seems to function just fine on the same outlook clients and phones that have an issue if the policy is set at the org level. 

 

We have a 2 node DAG and we're using roundrobin DNS for load balancing. I'm not 100% but it seems to be that the clients have an issue if they're connecting to the node that doesn't house the database that their mailbox is on. I think? There isn't anything that needs to be done to proxy the modern auth requests between the servers is there?

 

When I enabled the policy at the org level I start seeing unhandled exceptions in the event logs that all seem to point to some kind of duplicate key but I can't figure out what that duplicate key is... any thoughts? Here are some examples from the event log:

 

 

Log Name: Application
Source: MSExchange Front End HTTP Proxy
Event ID: 1003
Task Category: Core
Level: Error
Keywords: Classic
User: N/A
Description:
[Owa] An internal server error occurred. The unhandled exception was: Microsoft.Exchange.Collections.TimeoutCache.DuplicateKeyException: Cannot add a duplicate key. Use Insert instead
at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32& userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
at Microsoft.Exchange.HttpProxy.ProxyModule.IsLegacyAuthAllowed(HttpApplication httpApplication)
at Microsoft.Exchange.HttpProxy.ProxyModule.OnPostAuthenticateInternal(HttpApplication httpApplication)
at Microsoft.Exchange.Common.IL.ILUtil.DoTryFilterCatch(Action tryDelegate, Func`2 filterDelegate, Action`1 catchDelegate)
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="MSExchange Front End HTTP Proxy" />
<EventID Qualifiers="49152">1003</EventID>
<Level>2</Level>
<Task>1</Task>
<Keywords>0x80000000000000</Keywords>
<EventRecordID>861239</EventRecordID>
<Channel>Application</Channel>
<Security />
</System>
<EventData>
<Data>Owa</Data>
<Data>Microsoft.Exchange.Collections.TimeoutCache.DuplicateKeyException: Cannot add a duplicate key. Use Insert instead
at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32&amp; userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
at Microsoft.Exchange.HttpProxy.ProxyModule.IsLegacyAuthAllowed(HttpApplication httpApplication)
at Microsoft.Exchange.HttpProxy.ProxyModule.OnPostAuthenticateInternal(HttpApplication httpApplication)
at Microsoft.Exchange.Common.IL.ILUtil.DoTryFilterCatch(Action tryDelegate, Func`2 filterDelegate, Action`1 catchDelegate)</Data>
</EventData>
</Event>
Log Name:      Application
Source:        MSExchange Autodiscover
Event ID:      1
Task Category: Web
Level:         Error
Keywords:      Classic
User:          N/A
Description:
Unhandled Exception "Cannot add a duplicate key.  Use Insert instead"
Stack trace:    at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32& userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.IsLegacyAuthAllowed(HttpContext httpContext)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.OnAuthenticateRequest(Object source, EventArgs args)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="MSExchange Autodiscover" />
    <EventID Qualifiers="49152">1</EventID>
    <Level>2</Level>
    <Task>2</Task>
    <Keywords>0x80000000000000</Keywords>
    <EventRecordID>861169</EventRecordID>
    <Channel>Application</Channel>
    <Security />
  </System>
  <EventData>
    <Data>Cannot add a duplicate key.  Use Insert instead</Data>
    <Data>   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32&amp; userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.IsLegacyAuthAllowed(HttpContext httpContext)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.OnAuthenticateRequest(Object source, EventArgs args)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)</Data>
  </EventData>
</Event>
Log Name:      Application
Source:        MSExchange Front End HTTP Proxy
Event ID:      1003
Task Category: Core
Level:         Error
Keywords:      Classic
User:          N/A
Description:
[Ews] An internal server error occurred. The unhandled exception was: Microsoft.Exchange.Collections.TimeoutCache.DuplicateKeyException: Cannot add a duplicate key.  Use Insert instead
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32& userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.HttpProxy.ProxyModule.IsLegacyAuthAllowed(HttpApplication httpApplication)
   at Microsoft.Exchange.HttpProxy.ProxyModule.OnPostAuthenticateInternal(HttpApplication httpApplication)
   at Microsoft.Exchange.Common.IL.ILUtil.DoTryFilterCatch(Action tryDelegate, Func`2 filterDelegate, Action`1 catchDelegate)
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="MSExchange Front End HTTP Proxy" />
    <EventID Qualifiers="49152">1003</EventID>
    <Level>2</Level>
    <Task>1</Task>
    <Keywords>0x80000000000000</Keywords>
    <EventRecordID>861163</EventRecordID>
    <Channel>Application</Channel>
    <Security />
  </System>
  <EventData>
    <Data>Ews</Data>
    <Data>Microsoft.Exchange.Collections.TimeoutCache.DuplicateKeyException: Cannot add a duplicate key.  Use Insert instead
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32&amp; userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.HttpProxy.ProxyModule.IsLegacyAuthAllowed(HttpApplication httpApplication)
   at Microsoft.Exchange.HttpProxy.ProxyModule.OnPostAuthenticateInternal(HttpApplication httpApplication)
   at Microsoft.Exchange.Common.IL.ILUtil.DoTryFilterCatch(Action tryDelegate, Func`2 filterDelegate, Action`1 catchDelegate)</Data>
  </EventData>
</Event>
Log Name:      Application
Source:        ASP.NET 4.0.30319.0
Event ID:      1309
Task Category: Web Event
Level:         Warning
Keywords:      Classic
User:          N/A
Description:
Event code: 3005 
Event message: An unhandled exception has occurred. 
Event ID: f227e48f4d474111873957cee43f41ff 
Event sequence: 2 
Event occurrence: 1 
Event detail code: 0 
 
Application information: 
    Application domain: /LM/W3SVC/2/ROOT/EWS-2-132518667113847979 
    Trust level: Full 
    Application Virtual Path: /EWS 
    Application Path: C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\exchweb\EWS\ 
 
Process information: 
    Process ID: 12016 
    Process name: w3wp.exe 
    Account name: NT AUTHORITY\SYSTEM 
 
Exception information: 
    Exception type: DuplicateKeyException 
    Exception message: Cannot add a duplicate key.  Use Insert instead
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32& userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.IsLegacyAuthAllowed(HttpContext httpContext)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.OnAuthenticateRequest(Object source, EventArgs args)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


Request information: 
    Request URL: https://<computer name>.<domain>.com:444/EWS/Exchange.asmx 
    Request path: /EWS/Exchange.asmx 
    User host address: <internal IP>
    User: <domain>\<computer name>$ 
    Is authenticated: True 
    Authentication Type: Negotiate 
    Thread account name: NT AUTHORITY\SYSTEM 
 
Thread information: 
    Thread ID: 11 
    Thread account name: NT AUTHORITY\SYSTEM 
    Is impersonating: False 
    Stack trace:    at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32& userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.IsLegacyAuthAllowed(HttpContext httpContext)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.OnAuthenticateRequest(Object source, EventArgs args)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
 
 
Custom event details: 

Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="ASP.NET 4.0.30319.0" />
    <EventID Qualifiers="32768">1309</EventID>
    <Level>3</Level>
    <Task>3</Task>
    <Keywords>0x80000000000000</Keywords>
    <EventRecordID>861141</EventRecordID>
    <Channel>Application</Channel>
    <Security />
  </System>
  <EventData>
    <Data>3005</Data>
    <Data>An unhandled exception has occurred.</Data>
    <Data>f227e48f4d474111873957cee43f41ff</Data>
    <Data>2</Data>
    <Data>1</Data>
    <Data>0</Data>
    <Data>/LM/W3SVC/2/ROOT/EWS-2-132518667113847979</Data>
    <Data>Full</Data>
    <Data>/EWS</Data>
    <Data>C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\exchweb\EWS\</Data>
    <Data><computer name></Data>
    <Data>
    </Data>
    <Data>12016</Data>
    <Data>w3wp.exe</Data>
    <Data>NT AUTHORITY\SYSTEM</Data>
    <Data>DuplicateKeyException</Data>
    <Data>Cannot add a duplicate key.  Use Insert instead
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32&amp; userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.IsLegacyAuthAllowed(HttpContext httpContext)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.OnAuthenticateRequest(Object source, EventArgs args)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)

</Data>
    <Data>https://<computer name>.<domain>.com:444/EWS/Exchange.asmx</Data>
    <Data>/EWS/Exchange.asmx</Data>
    <Data><internal ip></Data>
    <Data><domain>\<computer name>$</Data>
    <Data>True</Data>
    <Data>Negotiate</Data>
    <Data>NT AUTHORITY\SYSTEM</Data>
    <Data>11</Data>
    <Data>NT AUTHORITY\SYSTEM</Data>
    <Data>False</Data>
    <Data>   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.CacheReader.AddEntry(String userKey, Int32 userPolicy, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyRepo.GetUserPolicy(String userKey, Int32 traceId, Int32&amp; userPolicy, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.FederatedAuthService.BasicAuthPolicyEvaluator.IsBasicAuthAllowed(String userKey, String protocolName, Int32 traceId, HttpApplication httpApplication, IRecipientSession recipientSession, IConfigurationSession configSession, ConfigWrapper config)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.IsLegacyAuthAllowed(HttpContext httpContext)
   at Microsoft.Exchange.Security.Authentication.BackendRehydrationModule.OnAuthenticateRequest(Object source, EventArgs args)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)
</Data>
  </EventData>
</Event>

@skreel - open a support case. 

Copper Contributor

@Greg Taylor - EXCHANGE  @The_Exchange_Team I opened a support case. They said they don't have a lot of experience with this... they're currently trying to ascertain if round robin DNS works for this... Should round robin DNS work as a front-end load balancing solution with legacy auth disabled at the org level?

 

I took memory dumps of a couple of the duplicate key exceptions but support says that they can't do anything with the dumps and they don't want them... I tried using windbg and SOS to figure it out on my own but without the symbols or source it's proving to be rather challenging for me... I don't think I'm going to get very far with support. They're saying we might just have to migrate all our mailboxes to the cloud... any help would be appreciated. Thanks!

Copper Contributor

Exceptions are showing up in the logs located at C:\Program Files\Microsoft\Exchange Server\V15\Logging\HttpProxy\Eas and C:\Program Files\Microsoft\Exchange Server\V15\Logging\HttpProxy\Autodiscover. I have not checked the other HttpProxy logs. Support is saying that no one uses this feature and that it's likely a problem with the code. I've been advised to just not disable legacy auth at the org level on premise and to either move the mailboxes to the cloud or to just disable legacy auth on a per user basis...

@skreel - can you please send me the case number in a private message. Thanks. 

Copper Contributor

The issue seems to be that when requests are proxied between nodes then legacy authentication needs to be enabled. When you disable legacy auth at the org level it also disables legacy auth for the proxying connection. The solution is to enable legacy auth on the computer accounts of the exchange servers. I wrote up how to do this on my blog. It's a hack though and I doubt it's supported by Microsoft.

@skreel - it's a workaround, but we really need to fix this. I'll keep pushing. 

Copper Contributor

@skreel Thanks for your contribution.

I was suffering from the same problem, no proxy between servers when default org policy sets to "Block Legacy Auth".
Workaround as suggested on your blog was editing computer auth policy attribute thru ADSI on Exchange Servers computer accounts object, it makes everything working well from client side.
Server side "Unhandled exceptions" keeps appearing to my environment on event viewer.

Copper Contributor

@bbzome yeah, it seems like this is only a partial workaround. Those unhandled duplicate key exceptions on the server still occur. @Greg Taylor - EXCHANGE do you think it's safe to run with the workaround or should we hold off for an official fix? Thanks!

Honestly, no. That sounds like a bad idea. Your idea of using per-account rather than org settings until we fix it sounds far more sensible. Engineering are looking at it. 

Copper Contributor

@Greg Taylor - EXCHANGE , we are experiencing the same problem as @skreel. We tested with individual users first and then applied it at the org level and immediately started having the flashing problem and we had to revert and set the default at the org level as $null. We have 3 different DAG's, front ended by Load Balancers. Is the recommendation to still apply it at the user level instead of at the org level?

Copper Contributor

@cdbrown I haven't heard any guidance otherwise 

The engineering team have agreed to fix this, but it's not going to ship for a CU or two, so until then, stick with per user policies. 

Copper Contributor

@Greg Taylor - EXCHANGE and @The_Exchange_Team we have enabled HMA and things seems to run good. But when we set authentication policy (pr user) we see some issues with password dialog boxes (Windows login prompt).

We have found out that it is related to BlockLegacyAuthMapi but ONLY if the client is on DirectAccess. If we disconnect DirectAccess everything seems to run smooth as well as if do it from a virtual client not connected to Direct Access.

 

We have 2 Exchange 2019 servers in DAG on CU8 with Big IP F5 loadmaster. 

 

Any suggestions?

@MrKnazure thanks for the feedback. It's been added to the notes for the issue being investigated. 

Copper Contributor

@Greg Taylor - EXCHANGE If we have all user mailboxes hosted on Exchange 2016, and have deployed Exchange 2019, can we safely enable the default Authentication policy for the Org, without effecting any user mailboxes that are hosted on Exchange 2016?

Set-OrganizationConfig -DefaultAuthenticationPolicy "Block Legacy Auth"

Can we then slowly start migrating users over to Exchange 2019 while blocking legacy auth for only those mailboxes migrated over to Exchange 2019?

 

Should we wait until @The_Exchange_Team  fixes the default org config before moving forward?

@Rob Whaley (EXCHANGE) - I believe the answer to this is yes, do you concur? 

@Exchange_Admin  and @Greg Taylor - EXCHANGE That is correct, Exchange 2019 Authentication Policies should only apply to mailboxes that are homed on an Exchange 2019 server.

Copper Contributor

@Greg Taylor - EXCHANGE  : With the release of CU9 KB5000631 is marked to be fixed. Does this mean the Events mentioned in the KB are no more triggered or the issue with being unable to set HMA Policies on the Org level is fixed as well?

 

Thanks as always!

I just checked with engineering and the answer is that yes, CU9 fixes both problems. The policies should now work and no event errors should be generated. 

Copper Contributor

That was much quicker than expected! Thanks Greg for validating, time to get this in place then :)

That was an easy one. Some comments here are much harder to respond to.... ;) 

Credit actually though goes to the people I asked... I'm just the messenger. 

Copper Contributor

@Greg Taylor - EXCHANGE It doesn't solve credential prompt loop when proxying connections on a DAG using HMA.

Copper Contributor

 

With a fully on-premises Exchange deployment, with no connection to Azure AAD, is there anything other than a legacy authentication protocol that can be used? Are there any plans from Microsoft to disable Basic Auth on Exchange OnPrem deployment?

Brass Contributor

@Greg Taylor - EXCHANGE : As mentioned by bbzome the issue with the flashing prompts seems still to be present even on CU9. Not sure if Engineering is aware therefor bringing this up again. Thanks!

Copper Contributor

Looking at the above Pre-requisites it talks about setting up Hybrid Modern Authentication.  What if everything is On-premise and you have nothing in the cloud?  I currently have one Exchange 2019  CU12 Server.  I do not have any cloud presence, or particularly want a cloud presence.  I am looking at Disabling Legacy Authentication.  Is there a way to do this On-premise without putting anything in the cloud?

Brass Contributor

@Greg Taylor - EXCHANGE 

 

we are exchange 2019 cu12 and create new auth policy to block all legacy protocol. upon assigning policy to user, they will experience issue like outlook for android password prompt, outlook client password prompt. per check the EAs on https log, the authenticationtype indicate bearer. what could be the reason user not able to login outlook for android? 

Copper Contributor

We have also activated a new Auth-Policy with which we have deactivated Legacy-Auth for MAPI and ActiveSync. As a result, Outlook clients were constantly popping up login-window and Outlook was unable to connect to the servers. We were able to solve the problem by deactivating Windows authentication for MAPI in the IIS frontend. I suspect that as long as the web server does not reject it, the clients try this auth method and then fail because of the policy.

Version history
Last update:
‎Jul 01 2019 04:37 PM
Updated by: