xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.47k stars 514 forks source link

Xamarin iOS CFNetwork issue with Apple's SSO Extension #9994

Open ameyapat opened 4 years ago

ameyapat commented 4 years ago

We are using Apple's SSO Extension on managed iOS devices to provide SSO functionality : SSO Extension

In iOS, on work place joined devices, sign in network requests to obtain tokens from Microsoft endpoints go through our SSO extension first to provide SSO for the managed account. Since the extension is present within our trusted broker (Microsoft Authenticator) it can immediately handle the network request and issue tokens or decide to not handle the request and pass it on to underlying System CFNetwork to handle the request. From the calling app’s perspective these requests are regular network requests and it doesn’t know they pass through our SSO extension.

The SSO extension decides not to handle the request by calling doNotHandle and the request should be passed on to CFNetwork like a regular network request. This seems to happen for native iOS apps, however for Xamarin built iOS apps the network request gets a timeout error and system logs indicate that the request was cancelled as evidenced by :

Task .<1> finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 UserInfo={NSErrorFailingURLStringKey=, NSErrorFailingURLKey=, _NSURLErrorRelatedURLSessionTaskErrorKey=, _NSURLErrorFailingURLSessionTaskErrorKey=, NSLocalizedDescription=}

NSURLErrorDomain Code=-999 : https://developer.apple.com/documentation/foundation/1508628-url_loading_system_error_codes/nsurlerrorcancelled?language=objc

This issue is only specific to Xamarin iOS apps and not iOS native apps. The xamarin version used is : 13.20.2.2

Expected Behavior

CFNetwork requests to go through and return their response when the flow goes through SSO Extension.

Actual Behavior

CFNetwork requests are being cancelled and a timeout exception is being returned when the flow goes through SSO extension.

Steps to Reproduce

Steps to reproduce involve work place joining device. The configuration profile downloaded post work place join contains config for SSO extension. Since it would involve specific account credentials, I've shared repro steps with @mandel-macaque

mandel-macaque commented 4 years ago

I see that you are using version 13.20.2.2 we did several fixes in the Handler code, can you please check that the issue does happen in a later release. I don't think those fixes will apply, but would be interesting to know.

Nevertheless I need a small example of the code that is used to perform the request in order to write either a small sample to reproduce it or identify possible issues.

Is the issue happening only on devices or does it happen in simulators too?

ameyapat commented 4 years ago

Hi @mandel-macaque , I tried using this project as sample code : https://github.com/Azure-Samples/active-directory-xamarin-native-v2

Your device needs to be MDM'd using the account I sent you via email in repro steps. ( I can send you the password via email if you don't have access) so that SSO extension is enabled on the device. Microsoft Authenticator needs to also be installed since the SSO extension lives within that app.

After the above steps are done, when trying to sign in, I get timeout : image

In Console I can see : Task <4C51F099-BD5A-4BC7-B451-0F13866DBC1E>.<1> finished with error [-999] Error Domain=NSURLErrorDomain Code=-999 UserInfo={NSErrorFailingURLStringKey=, NSErrorFailingURLKey=, _NSURLErrorRelatedURLSessionTaskErrorKey=, _NSURLErrorFailingURLSessionTaskErrorKey=, NSLocalizedDescription=}

ameyapat commented 4 years ago

@mandel-macaque I was debugging the Exception and the stack trace seems to be with message 'A task was canceled.' :

at System.Net.Http.NSUrlSessionHandler.SendAsync (System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) [0x001d4] in /Library/Frameworks/Xamarin.iOS.framework/Versions/14.2.0.12/src/Xamarin.iOS/Foundation/NSUrlSessionHandler.cs:527 at System.Net.Http.HttpClient.FinishSendAsyncBuffered (System.Threading.Tasks.Task1[TResult] sendTask, System.Net.Http.HttpRequestMessage request, System.Threading.CancellationTokenSource cts, System.Boolean disposeCts) [0x0017e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/external/corefx/src/System.Net.Http/src/System/Net/Http/HttpClient.cs:506 at Microsoft.Identity.Client.Http.HttpManager.ExecuteAsync (System.Uri endpoint, System.Collections.Generic.IDictionary2[TKey,TValue] headers, System.Net.Http.HttpContent body, System.Net.Http.HttpMethod method) [0x000c5] in :0 at Microsoft.Identity.Client.Http.HttpManager.ExecuteWithRetryAsync (System.Uri endpoint, System.Collections.Generic.IDictionary`2[TKey,TValue] headers, System.Net.Http.HttpContent body, System.Net.Http.HttpMethod method, Microsoft.Identity.Client.Core.ICoreLogger logger, System.Boolean doNotThrow, System.Boolean retry) [0x0013b] in :0