Troubleshooting MSAL.NET in Unity applications

MSAL 4.48.0 and above stopped using reflection on its net6 target. This is the only path forward with Unity.

Member not found at runtime

The issue

When using MSAL.NET in a Unity app, the application builds successfully. However at runtime, exceptions, like the ones below, are thrown that some members don't exist in MSAL.NET's code:

Error on deserializing read-only members in the class: No set method for property 'Claims' in type 'Microsoft.Identity.Client.OAuth2.OAuth2ResponseBase'.
  at System.Runtime.Serialization.DataContract+DataContractCriticalHelper.ThrowInvalidDataContractException
   (System.String message, System.Type type) [0x00000] in <00000000000000000000000000000000>:0 
  at System.Runtime.Serialization.DataContract.ThrowInvalidDataContractException
   (System.String message, System.Type type) [0x00000] in <00000000000000000000000000000000>:0 
Error setting value to 'TenantDiscoveryEndpoint' on 'Microsoft.Identity.Client.Instance.Discovery.InstanceDiscoveryResponse'.
 at Microsoft.Identity.Json.Serialization.ExpressionValueProvider.SetValue
   (System.Object target, System.Object value) [0x00000] in <00000000000000000000000000000000>:0 \r\n
 at Microsoft.Identity.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue
   (Microsoft.Identity.Json.Serialization.JsonProperty property, Microsoft.Identity.Json.JsonConverter propertyConverter,
     Microsoft.Identity.Json.Serialization.JsonContainerContract containerContract, Microsoft.Identity.Json.Serialization.JsonProperty containerProperty,
     Microsoft.Identity.Json.JsonReader reader, System.Object target) [0x00000] in <00000000000000000000000000000000>:0

Cause and solution

The issue comes from Unity IL2CPP plugin. When optimizing code (using code stripping), it removes needed dependencies for reflection to work (because it can't properly detect that usage). The MSAL.NET team investigated removing reflection related code from MSAL but it proved to be very impractical. Unity themselves have this documented in their docs (Managed code stripping) and recommend to use Link XML method as one of the solutions to this issue. This is our recommendation as well.

Add below entries into the root Assets/link.xml folder:

<linker>
 <assembly fullname="Microsoft.Identity.Client" preserve="all" />
 <assembly fullname="System" preserve="all" />
 <assembly fullname="System.Core" preserve="all" />
</linker>

See also

#1185, #2231