Search code examples
.netrestodatabasic-authenticationnav

Using basic authentication to consume NAV oData REST API in .NET


As in the title I'm trying to call a specific REST API - let's call it cursed_api - exposed by 3rd-party NAV Server, and to access it I need to provide username and password.

First point: to access it via web browser, for testing purposes, I do need to use Internet Explorer, because with other browsers (eg. Chrome or Firefox) I always get the same error: {"error":{"code":"Authentication_InvalidCredentials","message":"The server has rejected the client credentials."}}

But this is not the real problem. In Visual Studio solution I create an oData Connected Service, by the book. To download $metadata the only precaution is to add the authentication information (Authorization: Basic base 64 credentials) to the header.

Then I use the automatically generated code to try to call the cursed_api API, but I always get the same error message: {"error":{"code":"Authentication_InvalidCredentials","message":"The server has rejected the client credentials."}}

I tried adding authentication policies in request header, in this way:

static void GetCursedApiList()
{
    string serviceRoot = String.Format("{0}/Company('{1}')", endpoint.TrimEnd('/'), company);

    NAV.NAV context = new NAV.NAV(new Uri(serviceRoot));
    context.SendingRequest2 += SendBaseAuthCredsOnTheRequest;

    IEnumerable<CursedApiObject> cursedApiObjects = context.CursedApiObject.Execute();
}

static void SendBaseAuthCredsOnTheRequest(object sender, SendingRequest2EventArgs e)
{
    string creds = String.Format(@"{0}\{1}:{2}", domain, username, password);
    creds = String.Format(@"{0}:{1}", username, password);
    string base64Creds = Convert.ToBase64String(Encoding.ASCII.GetBytes(creds));

    e.RequestMessage.SetHeader("Authorization", String.Format("Basic {0}", base64Creds));
}

Then I tried using context credentials:

static void GetCursedApiList()
{
    string serviceRoot = String.Format("{0}/Company('{1}')", endpoint.TrimEnd('/'), company);

    NAV.NAV context = new NAV.NAV(new Uri(serviceRoot));
    context.Credentials = new NetworkCredential(username, password, domain);

    IEnumerable<CursedApiObject> cursedApiObjects = context.CursedApiObject.Execute();
}

But I had no luck.

Anyone who has faced the same problem?


Solution

  • Quite simple, the 3rd-party vendor had given me invalid credentials (which, in fact, is the error message returned).