1

I have an asp.net MVC 4 Web API that was created in VS2010. It is currently hosted on a Windows Server 2003 box running IIS 6.0. The API works great when I navigate to it using Google Chrome from my machine (on the same network as the server). The issue I am having is when I try to consume the API from a VS2013 C# console app. I am getting the following response:

{StatusCode: 401, ReasonPhrase: 'Unauthorized', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:

{ Server: Microsoft-IIS/6.0 WWW-Authenticate: Negotiate WWW-Authenticate: NTLM X-Powered-By: ASP.NET Date: Mon, 04 Apr 2016 16:09:50 GMT Content-Length: 1539 Content-Type: text/html }}

Here is the code for the console app:

static void Main(string[] args) {
    RunAsync().Wait();
    Console.ReadLine();
}

static async Task RunAsync() {
    using (var client = new HttpClient()) {
        client.BaseAddress = new Uri("http://server/website/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = await client.GetAsync("api/rateshop/1000/03/90210/");
        if (response.IsSuccessStatusCode) {
            RatingResultModel rateResults = await response.Content.ReadAsAsync<RatingResultModel>();
            foreach (var rate in rateResults.Rates) {
                Console.WriteLine("{0}\t${1}", rate.Service, rate.Rate);
            }
        } else {
            Console.WriteLine("{0}\n{1}", response.StatusCode, response.RequestMessage);
        }
    }
}

My actual WebAPI has [AllowAnonymous] above the ApiController.

The IIS 6.0 server has Anonymous Authentication enabled, and the current user is set to the server administrator, and I provided full control to the website directory for the administrator. Integrated Windows Authentication is also enabled.

So far everything I have searched for is either documentation on how to "Return a 401 status code" instead of what to do when a 401 status code is returned, or it is documentation on how to add authentication to a Web API instead of how to remove it. There seems to be very little on how to handle a Web API in IIS 6.0. As far as I can tell, anonymous authentication is enabled.

I have already tried this stackoverflow answer and I've followed MSDN's article on adding anonymous access to IIS 6.0. I don't believe I will need authentication or authorization security for this Web API since it is going to be used on a local network.

Given that the API works when I consume it with Google Chrome from my machine, what might be causing my issue with trying to use a console app to consume the Web API?

5
  • You can try adding the following in your web.config file: <security> <authorization> <add accessType="Allow" users="*" /> </authorization> </security> Commented Apr 4, 2016 at 17:22
  • Thank you @Hackerman, I have tried that as well with no luck. Commented Apr 4, 2016 at 17:40
  • can you do something like using (var clientHandler = new HttpClientHandler() { UseDefaultCredentials = true }) { using (var client = new HttpClient(clientHandler)) { } } and try? seems you have windows and anonymous both enabled so sending credentials with the request would be a good idea.. Commented Apr 4, 2016 at 19:55
  • @Nilesh that totally works, and makes sense! Thank you! Commented Apr 4, 2016 at 20:12
  • Windows Server 2003 has been dead for a few months already. Make sure you switch as soon as possible. Commented Apr 5, 2016 at 2:07

1 Answer 1

0

Thanks to @Nilesh for the answer.

Wrapping my RunAsync method in a using (var clientHandler = new HttpClientHandler() {UseDefaultCredentials = true}) did the trick.

Full solution:

using (var clientHandler = new HttpClientHandler()) {
    clientHandler.UseDefaultCredentials = true;

    using (var client = new HttpClient(clientHandler)) {
        client.BaseAddress = new Uri("http://server/website/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = await client.GetAsync("api/rateshop/1000/03/90210/");
        if (response.IsSuccessStatusCode) {
            RatingResultModel rateResults = await response.Content.ReadAsAsync<RatingResultModel>();
            foreach (var rate in rateResults.Rates) {
                Console.WriteLine("{0}\t${1}", rate.Service, rate.Rate);
            }
        } else {
            Console.WriteLine("{0}\n{1}", response.StatusCode, response.RequestMessage);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.