2

Problem

I'm getting a strange 401 Unauthorized Error when using the Windows.Web.Http.HttpClient on Xbox One. On Windows Machines everything is working fine. Credentials are Ok and I've tested on 3 different Xbox One - every time the same result.

Here is the code:

Windows.Web.Http.Filters.HttpBaseProtocolFilter filter = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
filter.AllowUI = false;
filter.CacheControl.WriteBehavior = Windows.Web.Http.Filters.HttpCacheWriteBehavior.NoCache;
filter.CacheControl.ReadBehavior = Windows.Web.Http.Filters.HttpCacheReadBehavior.NoCache;

Uri uri = new Uri("http://" + url + ":" + port + endpoint);

if (username != "" && password != "")
    filter.ServerCredential = new Windows.Security.Credentials.PasswordCredential(uri.OriginalString, username, password);

try
{
    HttpClient client = new HttpClient(filter);
    HttpResponseMessage response = await client.GetAsync(uri);

    response.EnsureSuccessStatusCode();

    var buffer = await response.Content.ReadAsBufferAsync();
    var byteArray = buffer.ToArray();

    return Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
}
catch
{
    return null;
}

Here is the Fiddler Output (I have hardcoded username/pass zu avoid any typing errors).

Xbox One:

GET http://192.168.178.31:XXXX/XXX/XXX HTTP/1.1
Accept-Encoding: gzip, deflate
Host: 192.168.178.31:XXXX
Connection: Keep-Alive
Pragma: no-cache

HTTP/1.1 401 Unauthorized 
Server: XXXX
Cache-Control: no-cache
WWW-Authenticate: Digest realm="XXXX", qop="auth", nonce="516f32c0f120024c220873c1ebc159e4", opaque="2effb29f8b3de0ca6a688330875890c8"
Connection: Keep-Alive
Content-Type: text/html
Content-Length: 432

Windows:

GET http://192.168.178.31:XXXX/XXX/XXX HTTP/1.1
Accept-Encoding: gzip, deflate
Host: 192.168.178.31:XXXX
Connection: Keep-Alive
Pragma: no-cache

HTTP/1.1 200 OK

Thanks

I created a small app with a few lines of Code again. Now with System.NET.Http instead of Windows.Web.Http.

Strange Thing now is, that I get a result like this in fiddler:

Windows:

HTTP 401 Text/Html
HTTP 200 Text/x-json

Xbox:

HTTP 401 Text/Html
HTTP 401 Text/Html

Workaround:

I'm now using both methods, if one fails it's trying with the other:

if (!digestFailed)
    filter.ServerCredential = new Windows.Security.Credentials.PasswordCredential(uri.OriginalString, username, password);
else
    request.Headers.Authorization = new HttpCredentialsHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", username, password))));

But there seems to be a big problem on the Xbox One. I played around with the web server. If I set authentication to digest only on the server, the Xbox is unable to connect! So I think there is something wrong with generating the digest on the Xbox with Windows.Security.Credentials.PasswordCredential?

To make it clear:

  • Server Authentication Basic:

    • Windows OK
    • Xbox OK
  • Server Authentication Digest:

    • Windows OK
    • Xbox FAILED
  • Server Authentication Digest + Basic:

    • Windows OK (Authenticated with Digest)
    • Xbox OK (Authenticated with Basic Auth)
  • 1
    Instead of `catch`ing all Exceptions without logging anything. Try to at least `catch (Exception e)` and inspect the `e` element, either through debugging/breakpoints or logging the Exception's content to the console. _You can find information on Exceptions and their properties at:_ [C# Exception Properties](https://msdn.microsoft.com/en-us/library/system.exception(v=vs.110).aspx#Properties) – janniks May 14 '18 at 08:10

1 Answers1

0

If I were you, I would definitely do what @janniks suggested in his comment - inspect the Exception that you're getting.

What is more important though, in such cases at least, you should have a proper way of investigating your network traffic. You can achieve that in two ways.

  1. The preferred way is to use Fiddler, which is a web debugging tool (basically allows you to inspect web traffic - i.e. requests and responses). Follow these instructions to hook up Fiddler with your Xbox.
  2. You could just use the Device Portal for Xbox and it's Http Monitor

Edit: Diagnosis

It's very hard to diagnose what is the problem you're facing without actually knowing and seeing what is happening. Nevertheless, I would check if the credentials that you're passing with the request are correct, as you're getting 401, which means

The request has not been applied because it lacks valid authentication credentials for the target resource.

Assuming that the credentials are correct, by the looks of what you have provided, it might be something to do with the Content-Type header you're setting on the request. The server might not understand that you're requesting it to format its response to text/html but it returns 200 when using text/x-json. Try using the latter (i.e. text/x-json) on the Xbox.

NOTE: You should probably use application/json (link) instead of Text/x-json, as the latter is unofficial/experimental

Having Fiddler working with your Xbox, I would fiddle around with these requests in it, instead of re-running the app ever time. Use Composer tab to manipulate the request headers or anything else for that matter.

Mikolaj Kieres
  • 4,137
  • 1
  • 20
  • 23
  • Yeah, code above is just an example. Normally I'm catch ing all exeptions. I've tried to debug with Fiddler, which is working fine for my Windows machine. Didn't know that I can use it with my Xbox. Thanks for the link so far and I will come back later with some results from fiddler. – Peter Frommert May 15 '18 at 06:28
  • Edited my answer :) – Mikolaj Kieres May 15 '18 at 23:09
  • Added my solution, but my Question is why `filter.ServerCredential` isn't working on Xbox One... – Peter Frommert May 16 '18 at 14:30
  • I can't find any information about how the request is being formatted when setting `ServerCredential`. I can only assume that it doesn't work because the `Request` is not formatted in a way that the server expects it to be. – Mikolaj Kieres May 16 '18 at 23:22
  • Updated my entry post, I really think there is something wrong with `ServerCredential` on the Xbox One... – Peter Frommert May 18 '18 at 07:14
  • From what you've written so far, it would appear that you have fiddler up and working and you are running the server locally. If I were you I would literally compare Windows and Xbox requests (the ones captured in fiddler) with each other. Check what's different (e.g. headers, content etc.), if they are the same, it means that the server is processing these request differently. In this case, just attach debugger and step through the code – Mikolaj Kieres May 18 '18 at 13:34