ASWebAuthenticationSession crashes Chrome on MacOS

API Endpoint(s) and/or Zoom API Event(s)
https://zoom.us/oauth
Dev environment: MacbookPro, Ventura 13.0.1, XCode 14.1

Description

I’m implementing a feature for an existing MacOS application, which will allow users to launch Zoom from the application. I’m trying to use ASWebAuthenticationSession to implement OAuth2 using an https-based redirect URI.

In my app delegate, I’ve implemented the following for universal links:

- (BOOL)application:(NSApplication *)application
 continueUserActivity:(NSUserActivity *)userActivity
 restorationHandler:(void (^)(NSArray<id<NSUserActivityRestoring>> *restorableObjects))restorationHandler
{
  if ([userActivity.activityType isEqualToString: NSUserActivityTypeBrowsingWeb]) {
    NSURL *url = userActivity.webpageURL;
    if ([url.path containsString:[NSString stringWithStdString:Zoom::kFragment]])
    {
      std::string urlStr((url.absoluteString).stdString); //DBG
      DialogFactory::GetInstance()->Message("Universal links handler - AppDelegate: Handling response: " + urlStr); //DBG
      return YES;
    }
  }
  return NO;
}

And here’s the code for the extension which conforms to ASWebAuthenticationPresentationContextProviding:

@objc extension ViewController : ASWebAuthenticationPresentationContextProviding {
     
  @objc public func userLogin(){
    guard let oauthMgr : ZoomOAuthMgr = self.oauthDelegate else {
      return
    }
     
    guard let authURL = oauthMgr.getAuthURL() else {
      return
    }
     
    guard let scheme = oauthMgr.getScheme() else {
      return
    }
     
    let session = ASWebAuthenticationSession(url: authURL, callbackURLScheme: scheme) { callbackURL, error in
      self.handleOAuthResponse(callbackUrl: callbackURL, err: error)
    }
     
    session.presentationContextProvider = self
    session.prefersEphemeralWebBrowserSession = true
    session.start()
  }
   
  func handleOAuthResponse(callbackUrl: URL?, err: Error?) {
    guard callbackUrl != nil else {return}
    guard err == nil else {
      /* Err handling */
      return
    }
     
    guard let url : URLComponents = URLComponents(string: callbackUrl!.absoluteString) else {return}
    guard let authCode = url.queryItems?.first(where: { $0.name == "code" })?.value else {return}
    /* Request access token */
  }
   
  public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
    return self.view.window ?? ASPresentationAnchor()
  }
}

Expected behaviour:
Starting a new session should launch the user’s default browser and present a login page. After the user is authenticated, the auth server’s response should be redirected to the app, where the session handler passed to ASWebAuthenticationSession handles the response.

Error?
When Chrome is the default browser, starting a session launches a Chrome window, which closes immediately. So no login page is presented. My session handler receives a copy of authURL that was sent to Chrome. No error is received by the handler or reported in XCode. No crash logs are generated. System logs don’t seem to offer any clues. And I see no evidence of network traffic suggesting the auth request was ever sent to the auth server.

When Safari is the default browser, starting a session launches Safari with the login page. After logging in, instead of redirecting back to the application and invoking my session handler, a 404 page is displayed, with a banner and a button with instructions: “Open in the MyApp app”. Clicking the button redirects back to the app, and the response, which should populate callbackURL is instead received by the universal links handler AppDelegate::application:continueUserActivity:restorationHandler: The response contains a valid auth code and no error. My session handler never receives the response or an error. No errors are reported in XCode.

When Firefox is the default browser, Safari is launched instead, and the behaviour is the same as above.

Sanity checks:
I’ve confirmed that

  • universal links are correctly configured and working as expected
  • the scheme passed to ASWebAuthenticationSession doesn’t contain any special characters and matches authURL’s scheme (https)
  • my system, including Chrome, is up to date

I’ve tried:

  • clearing all cache and cookies on Chrome
  • an alternate https-based redirect

Possible clue:
I’ve tried encoding authURL before handing it to ASWebAuthenticationSession, using various character sets, with no success. But if I encode authURL using the following character set: [urlStr stringByAddingPercentEncodingWithAllowedCharacters:NSCharacterSet.URLHostAllowedCharacterSet] - Chrome doesn’t crash. Instead it displays a popup with the message “Your connection to this site is not secure”.

I’d really appreciate any help getting this working as expected. Or any suggested alternatives for implementing OAuth with https-based redirects for a MacOS app.

Thanks!