ASWebAuthenticationSession only triggers universal links about 50% of the time

340 Views Asked by At

We have an OAuth flow in our application and we're performing the "authorisation step" by opening ASWebAuthenticationSession. When it completes, we parse out the query parameters from the callback URL, validate, and continue with the rest of the flow.

This works great with deep links (custom app schema), but becomes very "flaky" when using universal links.

From what I can gather, it looks like Safari verifies every navigation and determines whether it should trigger a universal link based on some heuristic. It'll be fine in about 50% of the attempts, but in the other 50% a regular navigation occurs and the user is just presented with our oauth callback URL (plus the corresponding successful or unsuccessful query parameters), leaving the ASWebAuthentication modal open.

Has anyone ever experienced anything like this? Any idea what could be causing this?

We tested/checked:

  • Using https as the callback URL scheme, or leaving it nil.

  • Redirecting back to a URL with a path.

  • Verified our universal link handling.

  • Compared all navigations (status codes, headers, anything) for differences between successful and unsuccessful flows. Nothing.

  • Dug through console logs.

  • Switched to performing OAuth against google as a backend, still fails 50% of the time.

  • Switched to using AppAuth instead of using our own solution. It also uses ASWebAuthSession and still fails 50% of the time.

2

There are 2 best solutions below

0
Dirk Jäckel On

In my experience when the universal link ends up on the web server, the only way to get back into our app is to let the user click on a link we generated on that page.

A redirect or JavaScript clicking on that link does not work. Looks like this is some kind of user protection.

Have you considered using URL schemes instead? If you do, the completion closure will be called. And Apple guarantees that your app will receive the callback and no other app, that registers the same scheme.

From the documentation:

ASWebAuthenticationSession ensures that only the calling app’s session receives the authentication callback, even when more than one app registers the same callback URL scheme.

In conclusion: Universal links only work well, if the user clicks on them.

0
vibroto On

The problem of universal link for redirect with ASWebAuthenticationSession is because it is in-app. There isn't an external app redirection.

Try to use a browser as external app to do the OAuth flow. Then you'll need to handle the redirection in your app delegate's scene(:continue userActivity:) method or application(:continue:restorationHandler:) if you don't works with scenes.

I use AppAuth SDK for iOS.

Instead of use

OIDAuthState.authState(byPresenting:presenting:prefersEphemeralSession:)

try to use

OIDAuthState.authState(byPresenting:externalUserAgent:)

let userAgent = OIDExternalUserAgentIOSCustomBrowser.customBrowserSafari()
currentAuthorizationFlow = OIDAuthState.authState(byPresenting: request, externalUserAgent: userAgent) { authState, error in
            if let authState = authState {
                self.setAuthState(authState)
                log(tag: .info, "Got authorization tokens. Access token: " +
                         "\(authState.lastTokenResponse?.accessToken ?? "nil")")
          
                self.saveState()
                self.performCompletionFromCurrentAuthState(completion: completion)
            } else {
                log(tag: .error, "Authorization error: \(error?.localizedDescription ?? "Unknown error")")
                self.setAuthState(nil)
            }
        }

Then, in my case I works with scenes, and the app handles the redirection in SceneDelegate like this

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    log(tag: .debug, "scene continue userActivity")
    
    if OpenIDHelper.shared.resumeExternalUserAgentFlow(url: userActivity.webpageURL) {
        return
    }
}

Source of inspiration: ASWebAuthenticationSession callbackURLScheme - https://forums.developer.apple.com/forums/thread/658334?answerId=638461022#638461022

Thanks "lapinka"