UnityWebRequest Embedding User + Password data for HTTP Basic Authentication not working on Android

13,245

Embedding username and password(http://username:[email protected]) in a url is no longer supported in some Applications and OS for security reasons.That's because this is not the standard way to perform HTTP Authentication. It very likely that Unity or Android did not implement this on the their side.

I tested this on the built-in Android Browser with http://Administrator:ZZh7y6dn@*IP Address*:8080/Thingworx/Things/SimulationData/Properties/OvenTemperature/ and it failed to function. So, I guess this problem is from Android.

I tested again without username and password http://*IP Address**:8080/Thingworx/Things/SimulationData/Properties/OvenTemperature/ then the login window appeared. When I entered the username and password, it worked.

You can still use UnityWebRequest to solve this problem by providing the AUTHORIZATION header to the UnityWebRequest with the SetRequestHeader function. This will only work if the authorization type is Basic instead of Digest. In your case, it is HTTP Basic.

For general solution:

string authenticate(string username, string password)
{
    string auth = username + ":" + password;
    auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
    auth = "Basic " + auth;
    return auth;
}

IEnumerator makeRequest()
{
    string authorization = authenticate("YourUserName", "YourPassWord");
    string url = "yourUrlWithoutUsernameAndPassword";


    UnityWebRequest www = UnityWebRequest.Get(url);
    www.SetRequestHeader("AUTHORIZATION", authorization);

    yield return www.Send();
    .......
}

For solution in your question:

public GameObject TempText;
static string TempValue;

void Start()
{
    StartCoroutine(GetText());
}

string authenticate(string username, string password)
{
    string auth = username + ":" + password;
    auth = System.Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(auth));
    auth = "Basic " + auth;
    return auth;
}

IEnumerator GetText()
{
    WaitForSeconds waitTime = new WaitForSeconds(2f); //Do the memory allocation once

    string authorization = authenticate("Administrator", "ZZh7y6dn");
    while (true)
    {
        yield return waitTime;
        string url = "http://*IP Address*:8080/Thingworx/Things/SimulationData/Properties/OvenTemperature/";


        UnityWebRequest www = UnityWebRequest.Get(url);
        www.SetRequestHeader("AUTHORIZATION", authorization);
        yield return www.Send();

        if (www.isError)
        {
            Debug.Log("Error while Receiving: " + www.error);
        }
        else
        {
            string result = www.downloadHandler.text;
            Char delimiter = '>';

            String[] substrings = result.Split(delimiter);
            foreach (var substring in substrings)
            {
                if (substring.Contains("</TD"))
                {
                    String[] Substrings1 = substring.Split('<');
                    Debug.Log(Substrings1[0].ToString() + "Temp Value");
                    TempValue = Substrings1[0].ToString();
                    TempText.GetComponent<TextMesh>().text = TempValue + "'C";
                }
            }
        }
    }
}
Share:
13,245
santhosh.r
Author by

santhosh.r

By Day - Technical consultant at Axcend Automation and Software Solutions Pvt Ltd. By Evening - Budding Coder learning stuffs around augmented reality, WebGL, PHP, javascript, etc

Updated on June 14, 2022

Comments

  • santhosh.r
    santhosh.r almost 2 years

    The Code below is used to get Temperature Value from Thingworx server that is hosted in one of our own systems. This works perfectly well in unity. But not in andoird, once apk is generated, it won't fetch any data from the server and there will be connection established. But, it just wont fetch the data and put that into the text mesh.

    I'm using unity 5.4.1 32bit . Check in both Android - 5.0.2 and 6.

    using UnityEngine;
    using System.Collections;
    using UnityEngine.Networking;
    using System.Text.RegularExpressions;
    using System;
    using UnityEngine.UI;
    
    public class  GETTempValue : MonoBehaviour {
    
    
    public GameObject TempText;
    static string TempValue;
    
    void Start() 
    {
        StartCoroutine(GetText());
    }
    
    IEnumerator GetText() 
    {
        Debug.Log("Inside Coroutine");
        while (true) 
        {
            yield return new WaitForSeconds(5f);
            string url = "http://Administrator:ZZh7y6dn@*IP Address*:8080/Thingworx/Things/SimulationData/Properties/OvenTemperature/";
    
            Debug.Log("Before UnityWebRequest");
            UnityWebRequest www = UnityWebRequest.Get (url);
            yield return www.Send();
            Debug.Log("After UnityWebRequest");
            if (www.isError) {
                Debug.Log ("Error while Receiving: "+www.error);
            } else {
                Debug.Log("Success. Received: "+www.downloadHandler.text);
                string result = www.downloadHandler.text;
                Char delimiter = '>';
    
                String[] substrings = result.Split(delimiter);
                foreach (var substring in substrings) 
                {
                    if (substring.Contains ("</TD")) 
                    {
                        String[] Substrings1 = substring.Split ('<');
                        Debug.Log (Substrings1[0].ToString()+"Temp Value");
                        TempValue = Substrings1 [0].ToString ();
                        TempText.GetComponent<TextMesh> ().text = TempValue+"'C";
                    }   
                }
            }
    
        }
    
    }
    
    }
    

    this is the android manifest permission

    uses-permission android:name="android.permission.INTERNET" 
    uses-permission android:name="android.permission.CAMERA"
    uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"
    uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"