4

The WebAuthenticationBroker doesn't seem to be able to handle navigation to my ms-app://. Just throws this ugly error as you will see below.

Steps

  1. Call AuthenticateAsync(), including callback uri obtained at runtime: WebAuthenticationBroker.GetCurrentApplicationCallbackUri()
  2. Go through authorize process, hit Allow.
  3. Instead of returning, the broker shows the page Can't connect to service. We can't connect to the service you need right now. Unable to do anything, so I hit the Back button visible.
  4. Debugger breaks on catch: "The specified protocol is unknown. (Exception from HRESULT: 0x800C000D)"

The callback for WebAuthenticationBroker.AuthenticateAsync() is received (according to Fiddler4 & the Event Viewer) but it throws the aforementioned exception as if it doesn't know how to interpret the ms-app:// protocol.

All examples imply my code should work but I think there's something less obvious causing an issue.

Code

private static string authorizeString =
  "https://api.imgur.com/oauth2/authorize?client_id=---------&response_type=token";

private Uri startUri = new Uri(authorizeString);

public async void RequestToken() {
  try {
    var war = await WebAuthenticationBroker.AuthenticateAsync(
      WebAuthenticationOptions.UseTitle
      , startUri);
      // Imgur knows my redirect URI, so I am not passing it through here

    if (war.ResponseStatus == WebAuthenticationStatus.Success) {
      var token = war.ResponseData;
    } 
  } catch (Exception e) { throw e; }
}

Event Viewer log excerpts (chronological order)

For information on how I obtained this, read the following MSDN: Web authentication problems (Windows). Unfortunately this is the only search result when querying authhost.exe navigation error.

  1. Information: AuthHost redirected to URL: <ms-app://s-1-15-2-504558873-2277781482-774653033-676865894-877042302-1411577334-1137525427/#access_token=------&expires_in=3600&token_type=bearer&refresh_token=------&account_username=------> from URL: <https://api.imgur.com/oauth2/authorize?client_id=------&response_type=token> with HttpStatusCode: 302.
  2. Error: AuthHost encountered a navigation error at URL: <https://api.imgur.com/oauth2/authorize?client_id=------&response_type=token> with StatusCode: 0x800C000D.
  3. Information: AuthHost encountered Meta Tag: mswebdialog-title with content: <Can't connect to the service>.

Thanks for reading, Stack. Don't fail me now!

erodewald
  • 1,815
  • 20
  • 45

2 Answers2

4

Afaik, you need to pass the end URL to AuthenticateAsync even if you assume that the remote service knows it.

The way WebAuthenticationBroker works is like the following: you specify an "endpoint" URL and when it encounters a link that starts with this URL, it will consider the authentication process complete and doesn't even try navigating to this URL anymore. So if you specify "foo://bar" as callback URI, navigating to "foo://bar" will finish the authentication, as will "foo://barbaz", but not "foo://baz".

Marcus Ilgner
  • 6,935
  • 2
  • 30
  • 44
  • I have also tried this with the same effect. I just pass in the CurrentApplicationCallbackUri() and it throws that exception, saying it doesn't understand the protocol. Also, I was finally able to get my developer license to register on my Surface, with the same outcome. So I guess that rules out any suspicion of Authhost.exe being "broken". – erodewald Feb 07 '13 at 14:10
  • I successfully used WebAuthenticationBroker with a non-http callback URI as described above. Can you check with a browser whether the generated HTML is correct on the server side? – Marcus Ilgner Feb 07 '13 at 17:07
  • Before I proceed, can you clarify your non-HTTP callback URI? Did you use the ms-app:// protocol or something else? And did you have to register it to have it work? – erodewald Feb 07 '13 at 17:54
  • We use a different protocol and it works without registration. As I tried to explain, the WebAuthenticationBroker just does a string comparison on the beginning of every URL and finalizes the process as soon as the beginning of the URL matches the endpoint it was given. No actual navigation to this URL is done. – Marcus Ilgner Feb 08 '13 at 10:08
  • Ah that's interesting. How would you go about verifying the actual URL the redirect attempts to navigate to? Having difficulties with Fiddler so that hasn't been a fruitful endeavor. When I throw the URI I build into a browser and hit Allow, there simply is no response from Imgur's server. Thanks very much for helping out by the way. – erodewald Feb 08 '13 at 13:30
  • Found the issue -- thanks very much for helping me come to the answer by forcing me to re-evaluate the aspects of AuthenticateAsync which I thought I knew to be correct. – erodewald Feb 08 '13 at 13:36
3

Resolved! @ma_il helped me understand how the broker actually evaluates the redirect callback and it led me back to square one where I realized I assumed WebAuthenticationOptions.UseTitle was the proper usage. Not so. Up against Imgur's API using a token, it requires WebAuthenticationOptions.None and it worked immediately.

As an example to future answer-seekers, here's my code.

    private const string clientId = "---------";
private static Uri endUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
private static string authorizeString = "https://api.imgur.com/oauth2/authorize?" 
                                          + "client_id=" 
                                          + clientId 
                                          + "&response_type=token" 
                                          + "&state=somestateyouwant" 
                                          + "&redirect_uri=" 
                                          + endUri;
private Uri startUri = new Uri(authorizeString);   


public async void RequestToken() {
  try {
    WebAuthenticationResult webAuthenticationResult =
      await WebAuthenticationBroker.AuthenticateAsync(WebAuthenticationOptions.None
                                                      , startUri
                                                      , endUri);

    if (webAuthenticationResult.ResponseStatus == WebAuthenticationStatus.Success) {
      string token = webAuthenticationResult.ResponseData;
      // now you have the token
    }
  } catch { throw; }
}
erodewald
  • 1,815
  • 20
  • 45