UNSOLVED

EvenLee

updated

9 years ago

E

EvenLee

4 Posts

0

9142

February 25th, 2018 20:00

C# connect unity rest API failed error: (401) Unauthorized

I manage to get info from Unity 450F, and the rest api works in RESTClient(a firefox extention). but C# does not.

In C#, I tried both boht Web client and  HttpWebRequest, even the third party libary(RestSharp), all failed.

WebClient:

var client = new WebClient();

//client.Headers.Add(HttpRequestHeader.Authorization, GetAuthHeader());

client.Credentials = new NetworkCredential(Credential.UserName, Credential.Password);

client.Headers["X-EMC-REST-CLIENT"] ="true";

client.Headers["Content-Type"] = "application/json";

client.Headers["Accept"] = "application/json";

  var response = client.DownloadString(url)

.......

WebRequest

HttpWebRequest request = HttpWebRequest.Create(uri) as HttpWebRequest;

request.Headers.Add("Authorization", GetAuthHeader());

//request.Headers.Add("Accept-Encoding", "gzip, deflate, br");

//request.Headers.Add("Accept-Language", "en-US,en;q=0.5");

request.Headers.Add("X-EMC-REST-CLIENT", "true");

request.ContentType = "application/json";

request.Accept= "application/json";

//request.Accept = "*/*";

string response;

using (Stream s = request.GetResponse().GetResponseStream())

{

     using (StreamReader sr = new StreamReader(s))

     {

          response = sr.ReadToEnd();

       }

  }

return response;

.......

private string GetAuthHeader()

{

     string auth = string.Format("{0}:{1}", Credential.UserName, Credential.Password);

     string enc = Convert.ToBase64String(Encoding.ASCII.GetBytes(auth));

     string cred = string.Format("{0} {1}", "Basic", enc);

      return cred;

  }

I also use the curl command generated by RESTClient:

curl -X GET -k -H 'Authorization: Basic XXXXXXXXXXXXXXXXXXXXX' -H 'X-EMC-REST-CLIENT: true' -i 'https://serverip/api/types/storageResource/instances/?fields=name,type,sizeTotal'

still not work, and I found this article, added the -L and -I command, still cannot get same result as from RESTClient.

  • mi hui

    1 Message

    7416

    1

    Posted July 1st, 2019 01:00

    I got the same issue.

    Here's my solution:

    1. Get the token "EMC-CSRF-TOKEN" with a "GET" request. Such as "/api/types/basicSystemInfo/instances". It's in the response header
    2. Put the "EMC-CSRF-TOKEN" in the "POST" request.

    It's solved my problem.

  • Rainer_EMC

    6 Operator

    8645 Posts

    7377

    0

    Posted July 3rd, 2019 07:00

    thanks for the feedback

  • EvenLee

    4 Posts

    7163

    0

    Posted July 29th, 2019 22:00

    Hi Hui,

    I've checked, /api/types/basicSystemInfo/instances do not have return header "EMC-CSRF-TOKEN",

    I do use api/types/system/instances, but got 302 not found, can you show some code of how to authenticate for the first time? thanks in advance.

  • EvenLee

    4 Posts

    7108

    0

    Posted August 1st, 2019 23:00

    after further digging, I got the solution in .netcore, hop it could help others. 

    ///


    /// EMC unity Api use cookies and redirect, but httpwebrequest will drop cookies when redirects,
    /// we have to do the process manually.
    ///
    ///
    ///
    private string GetRequestResponseWithRedirect(string url)
    {
    var result = string.Empty;
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

    request.CookieContainer = _cookies;

    //we will recall the redirected url by ourself
    request.AllowAutoRedirect = false;

    //EMC Unity API headers
    request.Headers.Add("Accept", "application/json");
    request.Headers.Add("Content-Type", "application/json");
    request.Headers.Add("Accept_Language", "en_US");
    request.Headers.Add("X-EMC-REST-CLIENT", "true");
    request.Headers.Add("Authorization", GetAuthHeader());

    HttpWebResponse response = null;
    try
    {
    response = (HttpWebResponse)request.GetResponse();
    }
    catch (WebException ex)
    {
    if (ex.Message.Contains("302"))
    {
    var webResponse = (HttpWebResponse)ex.Response;
    if (webResponse.Cookies.Count > 0)
    {
    //save any cookies we may need for the recall
    _cookies.Add(webResponse.Cookies);
    }

    //get the redirected url
    result = GetRequestResponseWithRedirect(ex.Response.Headers["Location"]);
    }

    }

    if (response != null)
    {
    // read the result when no errors.
    using (var stream = response.GetResponseStream())
    {
    using (var reader = new StreamReader(stream))
    {
    result = reader.ReadToEnd();

    }
    }
    }

    return result;
    }