From aabae4fb8fa2dc4586ca2e2b96176235549c3900 Mon Sep 17 00:00:00 2001 From: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com> Date: Wed, 3 Sep 2025 12:21:51 -0700 Subject: [PATCH 1/4] Mark project as AOT compatible for net 8 --- .../Accessors/LinuxKeyRingAccessor.cs | 6 +++--- ...Microsoft.Identity.Client.Extensions.Msal.csproj | 6 ++++++ .../Shared/Mac/LibSystem.cs | 4 ++-- .../Microsoft.Identity.Client.csproj | 4 ++-- .../Features/DesktopOS/Kerberos/NativeMethods.cs | 13 +++++++------ .../DesktopOS/Kerberos/TicketCacheWriter.cs | 2 +- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/client/Microsoft.Identity.Client.Extensions.Msal/Accessors/LinuxKeyRingAccessor.cs b/src/client/Microsoft.Identity.Client.Extensions.Msal/Accessors/LinuxKeyRingAccessor.cs index e0ec591630..4e5c56ebbb 100644 --- a/src/client/Microsoft.Identity.Client.Extensions.Msal/Accessors/LinuxKeyRingAccessor.cs +++ b/src/client/Microsoft.Identity.Client.Extensions.Msal/Accessors/LinuxKeyRingAccessor.cs @@ -101,7 +101,7 @@ public void Clear() { try { - GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); + GError err = Marshal.PtrToStructure(error); throw new InteropException( $"An error was encountered while clearing secret from keyring in the {nameof(Storage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'", err.Code); @@ -136,7 +136,7 @@ public byte[] Read() { try { - GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); + GError err = Marshal.PtrToStructure(error); throw new InteropException( $"An error was encountered while reading secret from keyring in the {nameof(Storage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'", err.Code); } @@ -181,7 +181,7 @@ public void Write(byte[] data) { try { - GError err = (GError)Marshal.PtrToStructure(error, typeof(GError)); + GError err = Marshal.PtrToStructure(error); string message = $"An error was encountered while saving secret to keyring in the {nameof(Storage)} domain:'{err.Domain}' code:'{err.Code}' message:'{err.Message}'"; throw new InteropException(message, err.Code); } diff --git a/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj b/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj index 6e8a31ea8e..e42dac1b2f 100644 --- a/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj +++ b/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj @@ -14,6 +14,12 @@ README.md + + true + true + true + + True diff --git a/src/client/Microsoft.Identity.Client.Extensions.Msal/Shared/Mac/LibSystem.cs b/src/client/Microsoft.Identity.Client.Extensions.Msal/Shared/Mac/LibSystem.cs index 079185ceb6..634c4bca1e 100644 --- a/src/client/Microsoft.Identity.Client.Extensions.Msal/Shared/Mac/LibSystem.cs +++ b/src/client/Microsoft.Identity.Client.Extensions.Msal/Shared/Mac/LibSystem.cs @@ -20,8 +20,8 @@ internal static class LibSystem public static IntPtr GetGlobal(IntPtr handle, string symbol) { - IntPtr ptr = dlsym(handle, symbol); - var structure = Marshal.PtrToStructure(ptr, typeof(IntPtr)); + IntPtr ptr = dlsym(handle, symbol); + var structure = Marshal.PtrToStructure(ptr); return (IntPtr)structure; } diff --git a/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj b/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj index 578bb27e45..f35fe4f953 100644 --- a/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj +++ b/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj @@ -109,14 +109,14 @@ - + + true true true - diff --git a/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/NativeMethods.cs b/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/NativeMethods.cs index 2f08a9daac..cc441e67fd 100644 --- a/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/NativeMethods.cs +++ b/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/NativeMethods.cs @@ -80,7 +80,7 @@ [Out] out LsaSafeHandle LsaHandle ); [DllImport(SECUR32)] - public static unsafe extern int LsaCallAuthenticationPackage( + public static extern unsafe int LsaCallAuthenticationPackage( LsaSafeHandle LsaHandle, int AuthenticationPackage, void* ProtocolSubmitBuffer, @@ -403,19 +403,20 @@ public void Dispose() } } + // Replace the usage of Marshal.PtrToStructure(IntPtr, Type) with the generic version Marshal.PtrToStructure(IntPtr) + // in the ForEachBuffer method inside SecBufferDesc struct. + private void ForEachBuffer(Action onBuffer) { for (int Index = 0; Index < cBuffers; Index++) { - int CurrentOffset = Index * Marshal.SizeOf(typeof(SecBuffer)); + int CurrentOffset = Index * Marshal.SizeOf(); - SecBuffer thisSecBuffer = (SecBuffer)Marshal.PtrToStructure( + SecBuffer thisSecBuffer = (SecBuffer)Marshal.PtrToStructure( IntPtr.Add( pBuffers, CurrentOffset - ), - typeof(SecBuffer) - ); + )); onBuffer(thisSecBuffer); } diff --git a/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/TicketCacheWriter.cs b/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/TicketCacheWriter.cs index e61c2a5605..9cb3f70918 100644 --- a/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/TicketCacheWriter.cs +++ b/src/client/Microsoft.Identity.Client/Platforms/Features/DesktopOS/Kerberos/TicketCacheWriter.cs @@ -102,7 +102,7 @@ public unsafe void ImportCredential(byte[] ticketBytes, long luid = 0) { MessageType = NativeMethods.KERB_PROTOCOL_MESSAGE_TYPE.KerbSubmitTicketMessage, KerbCredSize = ticketBytes.Length, - KerbCredOffset = Marshal.SizeOf(typeof(NativeMethods.KERB_SUBMIT_TKT_REQUEST)), + KerbCredOffset = Marshal.SizeOf(), LogonId = luid }; From b6fe1234071c733122131621c1aced9c32cb5cc5 Mon Sep 17 00:00:00 2001 From: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com> Date: Mon, 8 Sep 2025 10:27:10 -0700 Subject: [PATCH 2/4] Add AOT analyzer to build.props --- src/Directory.Build.props | 5 +++++ .../Microsoft.Identity.Client.Extensions.Msal.csproj | 6 ------ .../Microsoft.Identity.Client.csproj | 6 ------ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index d2054177b4..273cfe9b43 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -28,6 +28,11 @@ + + + true + + diff --git a/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj b/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj index e42dac1b2f..6e8a31ea8e 100644 --- a/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj +++ b/src/client/Microsoft.Identity.Client.Extensions.Msal/Microsoft.Identity.Client.Extensions.Msal.csproj @@ -14,12 +14,6 @@ README.md - - true - true - true - - True diff --git a/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj b/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj index f35fe4f953..2fbcd27067 100644 --- a/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj +++ b/src/client/Microsoft.Identity.Client/Microsoft.Identity.Client.csproj @@ -109,12 +109,6 @@ - - true - true - true - - From 793ef54149a7b7f79ab5996d5914a0e23b47bff0 Mon Sep 17 00:00:00 2001 From: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com> Date: Mon, 8 Sep 2025 11:54:38 -0700 Subject: [PATCH 3/4] Fix build errors for Android --- .../Broker/AndroidAccountManagerBroker.cs | 11 ++++--- .../AndroidBrokerInteractiveResponseHelper.cs | 33 ++++++++++++------- .../Broker/AndroidContentProviderBroker.cs | 13 +++++--- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidAccountManagerBroker.cs b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidAccountManagerBroker.cs index 21176836e7..a76920b428 100644 --- a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidAccountManagerBroker.cs +++ b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidAccountManagerBroker.cs @@ -350,14 +350,17 @@ public async Task InitiateBrokerHandshakeAsync() return; } - dynamic errorResult = JObject.Parse(helloRequestResult.GetString(BrokerConstants.BrokerResultV2)); + JObject errorResultObj = JObject.Parse(helloRequestResult.GetString(BrokerConstants.BrokerResultV2) ?? "{}"); string errorCode = null; string errorDescription = null; - if (!string.IsNullOrEmpty(errorResult)) + if (errorResultObj != null && errorResultObj.Count > 0) { - errorCode = errorResult[BrokerResponseConst.BrokerErrorCode]?.ToString(); - string errorMessage = errorResult[BrokerResponseConst.BrokerErrorMessage]?.ToString(); + JToken errorCodeToken = errorResultObj[BrokerResponseConst.BrokerErrorCode]; + errorCode = errorCodeToken?.ToString(); + + JToken errorMsgToken = errorResultObj[BrokerResponseConst.BrokerErrorMessage]; + string errorMessage = errorMsgToken?.ToString(); errorDescription = $"[Android broker] An error occurred during hand shake with the broker. Error: {errorCode} Error Message: {errorMessage}"; } else diff --git a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidBrokerInteractiveResponseHelper.cs b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidBrokerInteractiveResponseHelper.cs index f772e155e2..ad6e044be3 100644 --- a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidBrokerInteractiveResponseHelper.cs +++ b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidBrokerInteractiveResponseHelper.cs @@ -58,14 +58,18 @@ internal static void SetBrokerResult(Intent data, int resultCode, ILoggerAdapter case (int)BrokerResponseCode.BrowserCodeError: unreliableLogger?.Info("[Android broker] Response received - error. "); - dynamic errorResult = JObject.Parse(data.GetStringExtra(BrokerConstants.BrokerResultV2)); + JObject errorResultObj = JObject.Parse(data.GetStringExtra(BrokerConstants.BrokerResultV2) ?? "{}"); string error; string errorDescription; - if (errorResult != null) + + if (errorResultObj != null && errorResultObj.Count > 0) { - error = errorResult[BrokerResponseConst.BrokerErrorCode]?.ToString(); - errorDescription = errorResult[BrokerResponseConst.BrokerErrorMessage]?.ToString(); + JToken errorToken = errorResultObj[BrokerResponseConst.BrokerErrorCode]; + error = errorToken?.ToString(); + + JToken errorDescToken = errorResultObj[BrokerResponseConst.BrokerErrorMessage]; + errorDescription = errorDescToken?.ToString(); unreliableLogger?.Error($"[Android broker] error: {error} errorDescription {errorDescription}. "); } @@ -77,20 +81,27 @@ internal static void SetBrokerResult(Intent data, int resultCode, ILoggerAdapter } var httpResponse = new HttpResponse(); - //TODO: figure out how to get status code properly deserialized from JObject - httpResponse.Body = errorResult[BrokerResponseConst.BrokerHttpBody]?.ToString(); + //Get HTTP body from the JSON + JToken bodyToken = errorResultObj[BrokerResponseConst.BrokerHttpBody]; + httpResponse.Body = bodyToken?.ToString(); + + JToken subErrorToken = errorResultObj[BrokerResponseConst.BrokerSubError]; + JToken tenantIdToken = errorResultObj[BrokerResponseConst.TenantId]; + JToken upnToken = errorResultObj[BrokerResponseConst.UserName]; + JToken accountUserIdToken = errorResultObj[BrokerResponseConst.LocalAccountId]; + JToken authorityUrlToken = errorResultObj[BrokerResponseConst.Authority]; InteractiveBrokerTokenResponse = new MsalTokenResponse { Error = error, ErrorDescription = errorDescription, - SubError = errorResult[BrokerResponseConst.BrokerSubError], + SubError = subErrorToken?.ToString(), HttpResponse = httpResponse, CorrelationId = InteractiveRequestCorrelationId, - TenantId = errorResult[BrokerResponseConst.TenantId]?.ToString(), - Upn = errorResult[BrokerResponseConst.UserName]?.ToString(), - AccountUserId = errorResult[BrokerResponseConst.LocalAccountId]?.ToString(), - AuthorityUrl = errorResult[BrokerResponseConst.Authority]?.ToString(), + TenantId = tenantIdToken?.ToString(), + Upn = upnToken?.ToString(), + AccountUserId = accountUserIdToken?.ToString(), + AuthorityUrl = authorityUrlToken?.ToString(), }; break; default: diff --git a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs index 488ca3bf43..607b688d6f 100644 --- a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs +++ b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs @@ -18,6 +18,7 @@ using Microsoft.Identity.Client.UI; using Microsoft.Identity.Client.Utils; using Microsoft.Identity.Json.Linq; +using System.Diagnostics.CodeAnalysis; using AndroidNative = Android; using AndroidUri = Android.Net.Uri; @@ -73,14 +74,18 @@ public string GetProtocolKeyFromHandShakeResult(Bundle bundleResult) return negotiatedBrokerProtocalKey; } - dynamic errorResult = JObject.Parse(bundleResult?.GetString(BrokerConstants.BrokerResultV2)); + JObject errorResultObj = JObject.Parse(bundleResult?.GetString(BrokerConstants.BrokerResultV2) ?? "{}"); string errorCode = null; string errorDescription = null; - if (!string.IsNullOrEmpty(errorResult)) + if (errorResultObj != null && errorResultObj.Count > 0) { - errorCode = errorResult[BrokerResponseConst.BrokerErrorCode]?.ToString(); - string errorMessage = errorResult[BrokerResponseConst.BrokerErrorMessage]?.ToString(); + JToken errorCodeToken = errorResultObj[BrokerResponseConst.BrokerErrorCode]; + errorCode = errorCodeToken?.ToString(); + + JToken errorMessageToken = errorResultObj[BrokerResponseConst.BrokerErrorMessage]; + string errorMessage = errorMessageToken?.ToString(); + errorDescription = $"[Android broker] An error occurred during hand shake with the broker. Error: {errorCode} Error Message: {errorMessage}"; } else From 230c620f2c9b52d7b978bb93f92e7c79f7bafaca Mon Sep 17 00:00:00 2001 From: Neha Bhargava <61847233+neha-bhargava@users.noreply.github.com> Date: Wed, 10 Sep 2025 10:06:59 -0700 Subject: [PATCH 4/4] Address comments --- .../Android/Broker/AndroidContentProviderBroker.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs index 607b688d6f..16ed256313 100644 --- a/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs +++ b/src/client/Microsoft.Identity.Client/Platforms/Android/Broker/AndroidContentProviderBroker.cs @@ -66,12 +66,12 @@ private async Task GetHandShakeBundleResultFromBrokerAsync() public string GetProtocolKeyFromHandShakeResult(Bundle bundleResult) { - var negotiatedBrokerProtocalKey = bundleResult?.GetString(BrokerConstants.NegotiatedBPVersionKey); + var negotiatedBrokerProtocolKey = bundleResult?.GetString(BrokerConstants.NegotiatedBPVersionKey); - if (!string.IsNullOrEmpty(negotiatedBrokerProtocalKey)) + if (!string.IsNullOrEmpty(negotiatedBrokerProtocolKey)) { - _logger.Info(() => "[Android broker] Using broker protocol version: " + negotiatedBrokerProtocalKey); - return negotiatedBrokerProtocalKey; + _logger.Info(() => "[Android broker] Using broker protocol version: " + negotiatedBrokerProtocolKey); + return negotiatedBrokerProtocolKey; } JObject errorResultObj = JObject.Parse(bundleResult?.GetString(BrokerConstants.BrokerResultV2) ?? "{}");