Call Rest Service From Visual Studio -401-UnAuthorized Error

We are using single sign on to login to the Epicor System. We have enabled windows authentication from IIS manager. Please see below screen 1.

image

Also, we have configured internet option as follows.
image
When we are trying to access Rest Service from client machine using URL, it opened json file without any issue.
image
But when We try to access rest service from C#.code in client machine, following error was appeared. This code was copied from other thread in this site. It is attached below. We passed windows login and password to this method. (This is our administrator account)
Error

401 - Unauthorized: Access is denied due to invalid credentials.

You do not have permission to view this directory or page using the credentials that you supplied.

![image|624x351](upload://32qPuDRXMFtVocmVpOqb89yzvKe.jpg) Code static void Main(string[] args) { PrepareHeaders(); QueryCustomer(); }
    private static void QueryCustomer()
    {
        //Stand up which service to call
        HttpRequestMessage request = new HttpRequestMessage(
            HttpMethod.Post,
            ServiceUrl + "/Erp.Bo.CustomerSvc/GetByID");

        //Add the json payload
        request.Content =
            new StringContent(
                JsonConvert.SerializeObject(
                    new
                    {
                        custNum = 2
                    }),
                Encoding.Default,
                "application/json");

        try
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();

            //Make the call
            //ServicePointManager.ServerCertificateValidationCallback =
            //                                            delegate(object s, X509Certificate certificate,
            //                                                     X509Chain chain, SslPolicyErrors sslPolicyErrors)
            //                                            { return true; }; // Put By Nuwan to Avoid the remote certificate is invalid according to the validation procedure
            var response = httpClient.SendAsync(request).Result;

            stopwatch.Stop();
            var jsonResponse = GetObject(response);
            Console.WriteLine("Success:{0}", response.StatusCode == HttpStatusCode.Created);
            Console.WriteLine("Response:{0}", jsonResponse.ToString());
            Console.WriteLine("Duration:{0}", stopwatch.Elapsed.TotalMilliseconds);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
        Console.ReadLine();
    }

    public static JObject GetObject(HttpResponseMessage response)
    {
        string stringContent = string.Empty;

        if (response.Content != null)
        {
            stringContent = response.Content.ReadAsStringAsync().Result;
        }

        if (response.IsSuccessStatusCode)
        {
            if (!string.IsNullOrEmpty(stringContent))
                return JObject.Parse(stringContent);
        }
        else
        {
            throw new HttpRequestException(!string.IsNullOrEmpty(stringContent) ? stringContent : response.ReasonPhrase);
        }

        return null;
    }

    /// <summary>
    /// Set credentials and Session context
    /// </summary>
    private static void PrepareHeaders()
    {

        //var httpClientHandler = new HttpClientHandler()
        //{
        //    Credentials = new NetworkCredential(userName, password, "STRGRP"),
        //};

        //var httpClient = new HttpClient(httpClientHandler);
        //httpClient.DefaultRequestHeaders.Accept.Clear();
        //httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));


        //basic authorization example - just user and password in the header.
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
            Convert.ToBase64String(Encoding.ASCII.GetBytes(
                "{userName}:{password}")));

        //another option - token authentication - needs to be enabled in Epicor Admin Console
        //comment out previous basic authorization example and uncomment these 2 lines
        //string token = ObtainToken();
       // httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);

        //header to set company & plant(site)
        var hdrCallSettings = new CallSettings(companyID, plantID, "", "");
        httpClient.DefaultRequestHeaders.Add(hdrCallSettings.Name, JsonConvert.SerializeObject(hdrCallSettings));
    }
}

Can you check this?

I recall @Aaron_Moreng playing with REST and SSO in the not too distant past - perhaps he has some input.

If you need to Be-All ,End-All aka the holy grail of REST - call @Bart_Elia and @Olga

Have you tried accessing the page using Postman?

Mark W.

I would agree with Mark; first start with a REST client like Postman and see if you’re still getting the auth issue. I’d rather rule that out before digging through code

for basic authentication you need to specify Authorization header as
Basic [user]:[pwd] (in base64), and you need to specify epicor name and password, not Windows

Thank you for your comments. I will check this with postman and let you know the status.

I tried it from postman also, but i have the same error as customization. Should I used basic Auth or Bearer token authentication?
Please note that, We use Single sign on and I access the rest service from client machine. Also we are in Azure environment. Did I do some configuration wrong?

Hi,

This is the code that I use to call te REST API from an asp page.

I use the Web API interface to configure the REST calls.

Once you are able to call a rest service from within VS, extending it to the Epicor Rest API is relatively straightforward.

Best Regards,

Andrew.

I store a number of fields in an appsettings.config file

  • BuyerLateDeliveryJobReqs_URL - Rest URL

  • username - name of account set up on Epicor

  • password - password of account set up on Epicor

url = System.Configuration.ConfigurationManager.AppSettings[“BuyerLateDeliveryJobReqs_URL”];

            HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", "*");
            var client = new RestClient();


            
            string liveJobsURL = url + HttpContext.Current.Request.UrlReferrer.ToString().Substring(HttpContext.Current.Request.UrlReferrer.ToString().LastIndexOf('?') + 1);
            client.EndPoint = liveJobsURL;
            client.Method = HttpVerb.GET;
            client.PostData = "";

            json = client.MakeRequest(System.Configuration.ConfigurationManager.AppSettings["username"], System.Configuration.ConfigurationManager.AppSettings["password"]);

        
        var result = JsonConvert.DeserializeObject<ODataResponse<BuyerLateDeliveryJobReq>>(json);



        var resultob = (JsonConvert.SerializeObject(result));

        return (resultob);

Use basic auth for this test. Keep in mind, the user you’re entering is an Epicor account user, not the Windows account. Does the user you’re using have access within the ERP?

Maybe take a look at this thread, since you’re using Azure