aws-amplify / amplify-swift

A declarative library for application development using cloud services.
Apache License 2.0
454 stars 196 forks source link

signInWithWebUI.resultPublisher not firing on successful auth using authorization code flow with Universal Link redirect #1006

Closed blau2 closed 10 months ago

blau2 commented 3 years ago

Describe the bug We have Cognito configured to use the authorization code grant flow. From our iOS application, we initiate the auth flow using the hosted UI by calling Amplify.auth.signInWithWebUI.resultPublisher. Our redirect URL is a Universal Link which, upon successful authentication, deeplinks back into our iOS application with the authorization code in the query string, as expected. No event is emitted on the original subscription, however, and subsequent calls to Amplify.Auth.fetchAuthSession indicate that the user is not signed in. Is there a method that needs to be called on the deeplink callback to register the authorization code with Amplify? Or should this happen automatically under the hood?

To Reproduce Steps to reproduce the behavior:

  1. Execute the following:

    Amplify.Auth.signInWithWebUI(presentationAnchor: self.view.window!)
            .resultPublisher
            .sink {
                if case let .failure(authError) = $0 {
                    print("Sign in failed \(authError)")
                }
            }
            receiveValue: { _ in
                print("Sign in succeeded")
            }
            .store(in: &bindings)
  2. Authenticate

  3. Subscription does not fire event and session is not valid

Expected behavior signInWithWebUI.resultPublisher emits value, indicating that the user is authenticated.

Screenshots If applicable, add screenshots to help explain your problem.

Environment(please complete the following information):

Device Information (please complete the following information):

Additional context Add any other context about the problem here.

lawmicha commented 3 years ago

Hi @blau2, the documentation provides the example with registering a custom URL schema when you provision Cognito User Pool's Callback URLs and the Sign out URLs. Given this set up on the Cognito settings as "myapp://" and sample app with the updated CFBundleURLSchemes to have myapp, i was able to sign in using Facebook and then get a callback here from the SFAuthenticationSession with url:

myapp://?code=[CODE]&state=[STATE]

Can you clarify what happens when you call signInWithWebUI, successfully authenticate with the provider, and then

  1. do you get callback here so that the SDK can continue handling the url with code and state?
  2. Or does the SFAuthenticationSession navigate to your Universal Link, which then launches your App again?

If it is the first case, you can step through this logic to see if processURL was successful, which should eventually propagate the success or failure result back to the signInWithWebUI callback.

If it is the second case, this sounds like the flow of the App broken since signInWithWebUI launches a webview, which then redirects to your Universal Link, which then launches the App again.

Could you also expand on why you want the sign in redirect to be a Universal Link? What is the value of SignInRedirectURI and SignOutRedirectURI in amplifyconfiguration.json, is it something along the lines of https://[YourUniversalLink]? You can also set up multiple URLs in Cognito if your trying to have a redirect on different platforms, ie. JS can redirect to your universal link, and iOS can redirect to a custom URL schema.

blau2 commented 3 years ago

Hi @lawmicha, after successfully authenticating with the identity provider, SFAuthenticationSession redirects to our Universal Link which triggers the scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) callback, as expected. The app isn't launched again since it is already active and in the foreground. Nothing happens from that point onwards as signInWithWebUI.resultPublisher does not emit any value nor complete.

We are using Universal Links for our redirect for a couple of reasons:

  1. It is a more secure option than using a custom URL scheme (which any other app can register and therefore intercept, although unlikely). Apple recommends the use of Universal Links over URL schemes.
  2. It allows us to configure a single app client for all of our end clients.

For what it's worth, I've since moved on from Amplify and am using the AppAuth SDK for our OAuth needs.

lawmicha commented 3 years ago

Thanks for getting back to us. It sounds like signInWithWebUI.resultPublisher isn't called because the SFAuthenticationSession completion callback isn't triggered, due to the Universal link redirecting with the app in foreground calling the scene(_: willConnectTo) method. I'll mark this as a feature request for us to further investigate the Universal Link use case with HostedUI.

github-actions[bot] commented 3 years ago

This issue is stale because it has been open for 14 days with no activity. Please, provide an update or it will be automatically closed in 7 days.

harsh62 commented 10 months ago

@blau2 Since the release of Amplify V2, we have moved to using ASWebAuthenticationSession. In the latest version of Amplify V2, I see the result publisher being fired correctly.

I will close this issue as this seems to be fixed and no action is required on our part. If you still don't see it working, please reopen the issue with more details and I will be happy to investigate this further.

Thanks for your patience.

github-actions[bot] commented 10 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.