ActiveLogin / ActiveLogin.Authentication

Support Swedish BankID (svenskt BankID) authentication in .NET. Unofficial package, not created by BankID.
https://activelogin.net
MIT License
216 stars 75 forks source link

Embedded web view user agents not parsed as expected on Ios and Android #376

Closed span closed 1 year ago

span commented 2 years ago

Discussed in https://github.com/ActiveLogin/ActiveLogin.Authentication/discussions/375

Originally posted by **span** July 8, 2022 **Question** How can I return the `bankid:///` scheme BankID link as done in https://demo.activelogin.net when logging in through an embedded webview? **Describe the problem** When calling `Initialize` from Instagram embedded webview on Android and iOS (have not checked all versions), the App Link `https://app.bankid.com...` is received. The embedded views do not handle this link properly and cannot detect the device. To solve this, it seems to me the `bankid:///` link should be returned, as it is on the demo site. I cannot figure out how to do it, and I cannot verify the demo site source code (although I presume it is mostly similar to the samples?). I tried investigating the device detection and I ran the unit tests on the sample header below, and it correctly identifies it as Chrome and Android. Thus the App Link is resolved. However, when sniffing the traffic in a proxy to check what link is received from demo site, I get the `bankid:///` link! This is full response: ``` { "isAutoLaunch": true, "deviceMightRequireUserInteractionToLaunchBankIdApp": true, "checkStatus": true, "orderRef": "", "redirectUri": "bankid:///?autostarttoken=&redirect=null", "qrStartState": null, "qrCodeAsBase64": null } ``` **Request headers** ``` METHOD: POST URL /Api/Initialize HEADERS accept: application/json accept-encoding: gzip, deflate accept-language: en-SE,en-US;q=0.9,en;q=0.8,sv-SE;q=0.7,sv;q=0.6 connection: keep-alive content-length: 1702 content-type: application/json cookie: host: origin: referer: requestverificationtoken: sec-fetch-dest: empty sec-fetch-mode: cors sec-fetch-site: same-origin user-agent: Mozilla/5.0 (Linux; Android 12; IN2013 Build/RKQ1.211119.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36 Instagram 242.0.0.13.111 Android (31/12; 408dpi; 1080x2181; OnePlus; IN2013; OnePlus8; qcom; en_SE; 380288917) x-requested-with: com.instagram.android ``` **What area is it related to** Device detection, BankID App Launching **Expected behavior** The bankid:/// url should be returned as it is on the demo site since that will work. But how and why when device detection identifies it as Android and Chrome :S **NuGet package version** 5.0 **Runtime version** .net 6 **Smartphone (please complete the following information):** - Device: iPhone, iPad, OnePlus 8 **Workaround(s)** 1. I implemented a custom launcher that checked the `x-requested-with` header. If it exists, I return the `bankid:///` scheme. Did not fix things for iOS. 2. Use the UA parser that is non default. Currently under testing. If this works, perhaps the default device detections can/should be replaced? **Related issues** #360 #339 https://stackoverflow.com/questions/60878744/how-to-open-an-android-app-link-from-a-webview
span commented 2 years ago

This was converted from a discussion, here is a summary:

  1. On Android, the instagram webview is parsed as a Chrome web view, even when using firefox as main browser. Instagram is not able to open the App Link through the web view. Mozilla/5.0 (Linux; Android 12; IN2013 Build/RKQ1.211119.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36 Instagram 242.0.0.13.111 Android (31/12; 408dpi; 1080x2181; OnePlus; IN2013; OnePlus8; qcom; en_SE; 380288917)

  2. On Ios, the webview user agent is not recognised by the UAParserDeviceDetector. Mozilla/5.0 (iPad; CPU OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 221.0.0.9.115 (iPad14,1; iPadOS 15_1; sv_SE; sv-SE; scale=2.00; 750x1334; 349031919)

Both these issues result the the "app link" received by /Initialize is incorrect. Ios always wants a "app.bankid.com" link and firefox on android needs a "bankid:///" link.

span commented 2 years ago

I found the most non-destructive way for us to solve this was to:

  1. Use the UAParserDeviceDetector: services.AddTransient<IBankIdSupportedDeviceDetector, UAParserDeviceDetector>();
  2. A customIBankIdLauncher where the CanUseAppLink also responds true for unknown iOS browsers.
...

private static bool CanUseAppLink(BankIdSupportedDevice device)
{
    // Only Safari on IOS and Chrome or Edge on Android version >= 6 seems to support
    // the https://app.bankid.com/ launch url.
    //
    // We choose to default all ios devices with unknown browser to use the app link
    // though, since ios in-app webviews are detected as unknown but use safari rendering.

    return IsSafariOnIos(device)
            || IsUnknownOnIos(device)
            || IsChromeOrEdgeOnAndroid6OrGreater(device);
}

private static bool IsUnknownOnIos(BankIdSupportedDevice device)
{
    return device.DeviceOs == BankIdSupportedDeviceOs.Ios
            && device.DeviceBrowser == BankIdSupportedDeviceBrowser.Unknown;
}

...

Note that the "page refresh" bool is unchanged since at least the instagram browser does not reload the page.

PeterOrneholm commented 2 years ago

Hi!

Sorry for the late reply. I'm really away from the keyboard now during vacation. I will try to look at this in August. Two quick inputs (if that helps your debugging):

If you ned a "debugger" tool, I've built one and released it here: https://demo.activelogin.net/Debugger/Info

That page can help you understand how the current client is detected,.

tubbecool commented 2 years ago

Not surprised at all.

I've experienced so many issues with the universal link for BankId (https://app.bankid.com/). They shouldn't recommend us using it when it clearly doesn't work for the cases they say.

Glad you found a workaround

PeterOrneholm commented 2 years ago

I had a look at this now using our "debugger".

  1. On Android, the instagram webview is parsed as a Chrome web view, even when using firefox as main browser. Instagram is not able to open the App Link through the web view. Mozilla/5.0 (Linux; Android 12; IN2013 Build/RKQ1.211119.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/102.0.5005.125 Mobile Safari/537.36 Instagram 242.0.0.13.111 Android (31/12; 408dpi; 1080x2181; OnePlus; IN2013; OnePlus8; qcom; en_SE; 380288917)

https://demo.activelogin.net/Debugger/Info?UserAgent=Mozilla%2F5.0+%28Linux%3B+Android+12%3B+IN2013+Build%2FRKQ1.211119.001%3B+wv%29+AppleWebKit%2F537.36+%28KHTML%2C+like+Gecko%29+Version%2F4.0+Chrome%2F102.0.5005.125+Mobile+Safari%2F537.36+Instagram+242.0.0.13.111+Android+%2831%2F12%3B+408dpi%3B+1080x2181%3B+OnePlus%3B+IN2013%3B+OnePlus8%3B+qcom%3B+en_SE%3B+380288917%29&RedirectUrl=https%3A%2F%2Fdemo.activelogin.net%2FDebugger%2FInfo&AutoStartToken=afc686c2-7f36-40df-a973-3339e443c173&RelyingPartyReference=

  1. On Ios, the webview user agent is not recognised by the UAParserDeviceDetector. Mozilla/5.0 (iPad; CPU OS 15_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Instagram 221.0.0.9.115 (iPad14,1; iPadOS 15_1; sv_SE; sv-SE; scale=2.00; 750x1334; 349031919)

https://demo.activelogin.net/Debugger/Info?UserAgent=Mozilla%2F5.0+%28iPad%3B+CPU+OS+15_1+like+Mac+OS+X%29+AppleWebKit%2F605.1.15+%28KHTML%2C+like+Gecko%29+Mobile%2F15E148+Instagram+221.0.0.9.115+%28iPad14%2C1%3B+iPadOS+15_1%3B+sv_SE%3B+sv-SE%3B+scale%3D2.00%3B+750x1334%3B+349031919%29&RedirectUrl=https%3A%2F%2Fdemo.activelogin.net%2FDebugger%2FInfo&AutoStartToken=afc686c2-7f36-40df-a973-3339e443c173&RelyingPartyReference=

From what I can tell it detects Android and iOS correct and an "Unknown" browser. The "Launch Url" is therefore set to: Android: bankid:///?autostarttoken=afc686c2-7f36-40df-a973-3339e443c173&redirect=null iOS: bankid:///?autostarttoken=afc686c2-7f36-40df-a973-3339e443c173&redirect=

Is this not what you experience @span?

arevarnTH commented 1 year ago

Hi! We have the same problem as mentioned above. iOS app webview opens upp BankID, the user authenticates but then Safari is opened instead of returning back to the app. I have tried your debugger app through the webview in the app and launch url is "app.bankid.com". Anyone know how to get this right? What kind of launch url should be used for iOS webview?

PeterOrneholm commented 1 year ago

I think this could n ow be solved by #339 / #414. Closing this issue.