ASWebAuthenticationSession crashes Chrome on MacOS

Dev environment: MacbookPro, Ventura 13.0.1 XCode 14.1

I’m implementing a feature for an existing MacOS application, which will allow users to launch zoom meetings from the application, and am trying to use ASWebAuthenticationSession to implement OAuth2. I’ve confirmed that universal links are correctly configured and working for the app (which is 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
      /* TODO: guard */
      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 {
      /* TODO: 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}
    /* TODO: request access token */
  }
   
  public func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
    return self.view.window ?? ASPresentationAnchor()
  }
}

I've confirmed that the scheme passed to ASWebAuthenticationSession doesn't contain any special characters and matches the redirect URL scheme (https).

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 will handle the response.

Actual behaviour: 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 indicated 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. Also displayed is a banner near the top of the window, containing an 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:). My session handler never receives the response or an error. And no error is generated in XCode either.

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

Possible clue: I’ve tried encoding authURL before handing it to ASWebAuthenticationSession, using various character sets, with no success. But if I encode the authURL using the URLHostAllowedCharacterSet: [nsUrlStr 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 to get OAuth working with https-based redirects for a MacOS app.

Thanks!

This is a good writeup but difficult to diagnose without any logs or more information about the arguments you're using. Would you happen to be using http or https as your callbackURLScheme? If you're trying to use Universal Links instead of a custom scheme (which is possible but not the recommended path), you should use a nil callbackURLScheme. Safari will ignore http/https, but other browsers might get confused.

Hi,

Thanks for responding. I stated above that I'm using https as the callback scheme and that I'm using Universal Links instead of a custom scheme. But, I forgot to mention the following 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
  • disabling all extensions on Chrome
  • an alternate https-based redirect

If you tell me which logs would be helpful, I can send them to you. Is there some way to send them without attaching them here?

Also, you said:

Safari will ignore http/https, but other browsers might get confused.

I'm guessing you meant to say "Safari will not ignore http/https". If so, does this mean implementing OAuth using ASWebAuthenticationSession with an https redirect scheme and Universal Links only works with if the user's default browser is Safari?

Thanks.

ASWebAuthenticationSession crashes Chrome on MacOS
 
 
Q