AzureAD / microsoft-authentication-library-for-objc

Microsoft Authentication Library (MSAL) for iOS and macOS
http://aka.ms/aadv2
MIT License
264 stars 141 forks source link

Logging in via WebView doesn't block on ios "Save Password" prompt #848

Open PBoudreau opened 4 years ago

PBoudreau commented 4 years ago

When making the call to acquireToken, a web view is presented, into which the user enters their username and password.

Then, upon submitting those credentials, assuming they are valid, the web view will be automatically dismissed.

The problem is that this doesn't seem to allow for the user to interact with the Save Password iOS prompt, shown here:

image

Even though the prompt is briefly visible, the web view is quickly dismissed and this doesn't leave enough time for the user to interact with the prompt.

Is there a way to allow the web view to wait for the user to choose either to save the password or not before dismissing it?

Thank you!

oldalton commented 4 years ago

I think this needs to be handled on the website level. Website needs to wait a couple of seconds before redirecting back to the app with the authorization code.

Just to confirm, which iOS version are you using?

PBoudreau commented 4 years ago

Hi @oldalton and thank you for your reply!

We are using iOS 12.4 and later, including 13.x

About your suggestion of this being related to the website, I'm confused - isn't the MSAL library the one presenting the view controller with the web form, and therefore dismissing it once the login is completed?

Apologies if I'm missing something.

oldalton commented 4 years ago

Thanks. MSAL will not dismiss web view until it gets an authorization code from the website. What happens after credentials are collected, is that client is redirected to a special URL which starts with your redirectUri and contains authorization code in it. The moment when this redirect happens, is up to the identity provider to decide. Furthermore, if you're using default ASWebAuthenticationSession-type webview, MSAL doesn't even dismiss it by itself, it's all handled by iOS following the logic described above.

PBoudreau commented 4 years ago

Thanks @oldalton - with the additional explanation you provided above, I'll go back and re-check our implementation and try to see if I can understand how to prevent an early dismissal.

If you don't mind, we could keep this issue open and I'll post back my findings / additional questions / solution for anyone else to benefit from in the future.

PBoudreau commented 4 years ago

Alright, I spent some time reviewing our implementation and will try to explain what I'm seeing.

First, although our current integration of MSAL is fully functional, the AppDelegate's callback function func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool is never called. So the app doesn't get a chance to pause to let the user choose to save the password or not, since the web form is immediately dismissed following the submission of valid credentials.

In order for the callback to get invoked, and allow me to possibly introduce a delay before the form is dismissed, I had to change the webViewType on the MSALWebviewParameters instance to .safariViewController, like so:

let webviewParameters = MSALWebviewParameters(parentViewController: rootViewController)
webviewParameters.webviewType = .safariViewController

Now that the callback is called, I can look into the possibility of adding a delay. But this still feels inadequate, since when the iOS auto-fill feature prompts the user to save or not the credentials they just entered (see screenshot provided previously), it is expected that the user responds via the prompt by choosing either Save Password or Not Now before the login flow continues. But instead, introducing a delay will simply cause the prompt and the web form to automatically disappear after said delay, without the user's intervention, which is not ideal user interaction.

So I guess I'm at the point where I can proceed with the introduction of the delay, but I'm wondering if perhaps there's something better that could be done to provide the usual auto-fill experience, letting the user interact with the prompt before continuing the login flow.

oldalton commented 4 years ago

I wouldn't recommend adding a delay on the client side. This scenario needs to be handled by the webpage itself and the webpage needs to handle this use case correctly.

PBoudreau commented 4 years ago

Ok, that makes sense. I will reach out to the people knowledgeable and in control of the web page to see if they can do this.

Perhaps they could report back their findings here in case it's helpful to others in the future?

PBoudreau commented 4 years ago

For reference, I just found a couple more posts by others faced with a similar problem:

https://forums.developer.apple.com/thread/127979 https://github.com/openid/AppAuth-iOS/issues/78

PBoudreau commented 4 years ago

Since my last update, I got around to testing login on a physical device running iOS 12.4.5, with the same login web page, same version of the app, same version of MSAL, and it turns out that the web page will block when the OS prompts the user to save or not the credentials that were entered.

I was also able to reproduce this behaviour on a simulator running iOS 12.4.

However: I downloaded the MSAL sample app and, on both iOS 12.4 and 13.3, the Save Password prompt isn't blocking: the web page is quickly dismissed after valid credentials have been entered.

So I'm beginning to be really confused: why would our app pause on the Save Password prompt on iOS 12.4, but not 13, while the MSAL sample app never pauses? Any thoughts regarding these new findings?

I'm attaching the screen recordings I made of my testing of the Sample MSAL app on both iOS 12.4 and 13.3. The dismissal happens quite fast; it helps to step through the movie frame by frame to see it happening.

12.4: https://share.getcloudapp.com/v1urmKBe 13.3: https://share.getcloudapp.com/bLumG6Ql

PBoudreau commented 4 years ago

Hello @oldalton - I was curious to know if you had a chance to confirm whether you could reproduce the issue using the sample app. Don't hesitate to reach out to me if I can help in any way. Thanks!

skamoda commented 4 years ago

Hi, in our project we expected the same issue. Is there some solution or workaround to this problem?

antrix1989 commented 4 years ago

We will file feedback to Apple regarding this.

PBoudreau commented 4 years ago

Thanks for the update @antrix1989 !

Would appreciate if you could report back any updates regarding this issue as we were counting on the native password saving experience provided by the OS to alleviate the burden from our users of always having to enter credentials.

antrix1989 commented 4 years ago

Reported this to the Apple, feedback ID: FB7645626

PBoudreau commented 4 years ago

Thank you @antrix1989 !

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. Please provide additional information if requested. Thank you for your contributions.

PBoudreau commented 4 years ago

As I'm still very much interested in what Apple will have to say regarding this issue, I'd just like to make sure it doesn't auto-closed for a lack of activity while we wait to hear back from them.

antrix1989 commented 4 years ago

Hi @PBoudreau,

Apple needs a sample app to repro the issue. Would you be able to send it to my email? I assume we will need a test user credentials as well.

My email is sedemche@microsoft.com.

Thanks!

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. Please provide additional information if requested. Thank you for your contributions.

jasoncoolmax commented 4 years ago

We have already reported the issue to Apple. We will update once we hear back from Apple.

PBoudreau commented 4 years ago

Hello, would it be possible to keep this issue open in order to track Apple's response in the matter?

oldalton commented 4 years ago

Marking as internal to get it excluded from stale checks while we're waiting for a reply from Apple. Thanks!

nrichard-neudesic commented 3 years ago

Hello, I am wondering if there has been a response from Apple regarding this issue? Any feedback would be greatly appreciated as this is a point of frustration for our consumers.

ekscrypto commented 3 years ago

We have partially fixed this issue in one of our project by using a custom WKWebView, this allows us to control when the view is dismissed. There is some magic needed to detect when the user is prompted to saving his password, which due to code copyright issues I cannot share here.

I believe using a custom WKWebView is the way to solve this issue.

mipetriu commented 3 years ago

I had the opportunity to bring up this issue for ASWebAuthenticationSession in a different Apple support channel than our pending bug report, and they unfortunately confirmed that this is a bug that needs to be addressed by their Authentication team.

I wanted to mention that we don't recommend using a WKWebView with custom manipulation, and while it may work to enable using TouchID to sign in, FaceID is only available with ASWebAuthentication session.

A potential workaround is to add a landing page to your web auth flow that tells the user "You logged in successfully" and contains a "done" or "return to app" button that they can press once they've interacted with the Save Password prompt. That way, no custom manipulation to the webview is needed to interact with the prompt, and will also allow the use of ASWebAuthenticationSession.

sparks2209 commented 8 months ago

Hi, can someone help what will be potential fix for this issue, as today by using webViewParameters.webviewType = .safariViewController, the popup for Save Password disappears automatically. And this popuo comes only once.