Does AsWebAuthenticationsession support universal links?

Viewed 1122

I use AsWebAuthenticationsession to authenticate from another application to my application. I open AsWebAuthenticationsession, and it redirects my application's universal links. The problem is when it redirects my application universal link, it asks to open the App Store. When it redirects I want to close the session. But AsWebAuthenticationsession only takes a custom URL Scheme. How can I handle it securely (because custom URL Schemes are not secure: RFC8252 7.1)

2 Answers

I can confirm this works as of iOS 14 or later, haven't tested on earlier versions though.

When you initialize your ASWebAuthenticationSession you can pass in callbackURLScheme: "https".

When the authentication provider redirects to your universal link, your app delegate's application(_:continue:restorationHandler:) will fire with the correct redirect url, however the ASWebAuthenticationSession's completion handler does not fire and therefore the authentication dialog remains on the screen.

You will need to save a reference to the ASWebAuthenticationSession and cancel() it manually to dismiss it instead.

You can try with this method

To add a singleton class to handle this callback

SceneDelegate.swift

@available(iOS 13.0, *)

func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {

    // handle here

    OAuthManager.instance.callBackUserActivity(userActivity: userActivity)

}

OAuthManager.swift

import Foundation

import AuthenticationServices



protocol UserActivityListener {

func callBackUserActivity( userActivity : NSUserActivity )

}



class OAuthManager {

public static let instance = OAuthManager()

var asWebSession: ASWebAuthenticationSession?

}

extension OAuthManager : UserActivityListener {

func callBackUserActivity(userActivity: NSUserActivity) {

    // Get URL components from the incoming user activity.

    guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,

          let incomingURL = userActivity.webpageURL,

          let components = NSURLComponents(url: incomingURL,    resolvingAgainstBaseURL: true) else {

        return

    }

    

    // Check for specific URL components that you need.

    guard let path = components.path,

          let params = components.queryItems else {

        return

    }
    // cancel your ASWebAuthenticationSession
    asWebSession?.cancel()


    print("path = \(userActivity.webpageURL)")



    if let token = params.first(where: { $0.name == "token" })?.value {

        print("token = \(token)")

    }

  }


 }

YourViewController.swift

class YourViewController: UIViewController {
// set your instance
var oauthManager = OAuthManager.instance


private func startSignInAsWebAuthSession() {
    let callbackURLScheme = "YOURAPP"
    guard let authURL = URL(string: "YOUR URL LINK") else { return }
        
        self.oauthManager.asWebSession = ASWebAuthenticationSession.init(url: authURL, callbackURLScheme: callbackURLScheme,completionHandler: { callbackURL, error in
            // we dont listen to the call back, this web authentication session only open for login only
        })
        
        oauthManager.asWebSession?.prefersEphemeralWebBrowserSession = true
        oauthManager.asWebSession?.presentationContextProvider = self
        oauthManager.asWebSession?.start()
}
}

extension YourViewController:    ASWebAuthenticationPresentationContextProviding {
   func presentationAnchor(for session: ASWebAuthenticationSession) ->     ASPresentationAnchor {
       ASPresentationAnchor()
    }
  }
Related