problem and solution, posting user credentials to https website with webview

MPossethMPosseth Member
edited October 8 in Xamarin.Forms

Hello

I have an Android Xamarin app that injects HTML into a Xamarin forms webview to perform a post to our https website

I use the following method :

In the main page i have a login form in XAML when the user presses the login button I hide the stacklayout of this 'native' form
retrieve the username and password from the textboxes and replace dummy values in a HTML string that i inject in the Webview

         private  const string LogonForm = "<html><head><title>Logon</title>"
                        + "<script type=\"text/javascript\">"
                        + "function submitForm() {"
                        + "document.forms[0].submit();}"
                        + "</script>"
                        + "</head>"
                        + "<body bgcolor=\"#002B60\" onload=\"submitForm();\">"
                        + "<form method=\"POST\" action=\"" + BaseUri + "login/index\">"
                        + "<input type=\"hidden\" name=\"txtUserName\" value=\"#var:username#\"/>"
                        + "<input type=\"hidden\" name=\"txtPassword\" value=\"#var:password#\"/>"
                        + "<input type=\"hidden\" name=\"intStype\" value=\"1\" />"
                        + "</form>"
                        + "</body>"
                        + "</html>";
          private HtmlWebViewSource HtmlContent()
        {
          var html = new HtmlWebViewSource
         {
            Html = LogonForm.Replace("#var:username#",txtUserName.Text).Replace("#var:password#", txtPassword.Text)
           };
          return html;
      }
    /// <summary>
    /// MP: Try the logon procedure, check if we are connected to internet 
    ///     also check if we want demo usage or if we are a 'normal' user 
    /// </summary>
    private void TryLogon(int Timeout)
    {

        if (InternetIsAvaillabe())
        {


            IsBussyLogIn = true;
            MainStackLayout.IsVisible = false;
            MainWebView.IsVisible = true;

           MainWebView.Source = HtmlContent();

This worked fine ! until some days ago ,,,,,, for some strange reason this code works still perfectly in the Emulator in Visual Studio 2019 ( 16.3.2 )
but not on a physical device ( Nokia Scirocco Android 9 , Samsung Galaxy S8 Android 9 , Huawei Y6+ Android 9 )

So I spend my time banging my head on my desk to solve this problem as the Webview showed a blank page but it was actually logged into the website and i could even see the Drop down menu`s appear but NOT the content of the website .

After hours of debugging and trying ... I found that setting the source of the Webview to a null pointer before assigning the HTMLContent solved this problem and the app is behaving as expected .

       private void TryLogon(int Timeout)
      {
        MainWebView.Source = null;
        if (InternetIsAvaillabe())
        {


            IsBussyLogIn = true;
            MainStackLayout.IsVisible = false;
            MainWebView.IsVisible = true;

           MainWebView.Source = HtmlContent();

So for anyone struggling with this issue and maybe for someone who can explain this behavior I post this here ..

Posts

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    but not on a physical device ( Nokia Scirocco Android 9 , Samsung Galaxy S8 Android 9 , Huawei Y6+ Android 9 )

    If I met this kind of issue, first of all, to remove out of custom OS issue, we will test it in the Google device, such as the Google Pixel, Nexus. Becuase of this custom OS, just like MIUI or EMUI will have some wired issue.

    If you set MainWebView.Source = null; you init the webview, this function is same as the refresh, you can test it with webView.Reload(); before MainWebView.Source = HtmlContent();;

  • MPossethMPosseth Member

    Hello Leon,

    I use the XAML WebView of Xamarin forms ( 4.2.0.848062 )
    <WebView x:Name="MainWebView" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" IsVisible="False" android:WebView.EnableZoomControls="true" android:WebView.DisplayZoomControls="true"/>

    It shows at the 'Reload' method in the C# code 'To be added ' and VS 2019 red underlines the call as not valid

    The fun fact is .... that the app was working fine in it`s previous state , but i understood that Google made some security changes in the browser engine about mixed content in Android .

    So my guess is that the HTML that i inject is seen as unsafe or something like that, but as the order is now changed of the requests by the re init it is accepted, thus before the cycle was

    Safe to Unsafe to Safe ( as the webview inits with a https uri )
    now as you state the Null pointer is the same as a init
    Unsafe to Safe ( which is not a violation )

    So maybe this helps explaining this behavior,,, I am still surprised and happy that the Null pointer did the trick however I still think it is a bit strange that nobody else seemed to encounter this ( I googled a lot about the subject ) or maybe I am the first?.

    But hey i also see all sorts of fancy code for posting data with the webview while mine is only a few lines of code and platform independent and also needed by the webview engine as the site it points to is a SPA with a session authentication engine ( membership provider ) .

    The Nokia Sirocco runs Android One it is my personal device and thus has the latest ( 1 september security patch ) patches
    the other devices are 'standard manufacturer' Android 9 flavors , but they all had the exact same behavior.

    As I work for a Energy billing company and the app gives insight to consumption data it needs to run on every possible Android device we support ( Android 7 to 10 ) ,However I will ask my employer for a Google Pixel or Nexus for the next projects on Android just to be sure :-)

Sign In or Register to comment.