16

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)

Community
  • 1
  • 1
Hüseyin
  • 250
  • 1
  • 13
  • This Apple forum thread may help but it's still unclear :( https://developer.apple.com/forums/thread/658334 – TruMan1 Oct 29 '20 at 03:00
  • 1
    Workaround Solution : I passed callbackURLScheme empty string and I handled universal link with userActivity and after that canceled ASWebAuthenticationSession. I staticky defined ASWebAuthenticationSession. – Hüseyin Nov 06 '20 at 12:54
  • That's a really good question. I could get it work as @Hüseyin suggested. But as always `SFAuthenticationSession`, for pre iOS 12 devices, doesn't seem to work that way ... – Oliver Apr 29 '21 at 13:57
  • @Hüseyin Can you please share the answer with some more details, if you get time? This seems case doesn't seem to have much documentation, and since you have figured out a way to do that, it'd be good to get to know the details. Thank you so much! – Shobhit Puri Jan 28 '22 at 08:09
  • @Hüseyin Unfortunately, this option does not work for me. Perhaps there are some nuances in this option. At the same time, the universal links themselves have been configured and working for a long time. – pier_nasos May 28 '23 at 09:02

2 Answers2

5

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.

stevesw
  • 1,055
  • 10
  • 15
  • Unfortunately, this option does not work for me. I tried to transmit "https", an empty string, nil, the entire redirect url. None of the options work. At the same time, if authorization is performed through an external Safari browser, then the redirect back to the application is successfully performed. – pier_nasos May 28 '23 at 08:52
0

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()
    }
  }
WCY
  • 23
  • 4