14

So I've been working with DotNetOpenAuth for a while, Today I needed to add support for provider that forces me to send the secret key with Basic authentication (I've been using an old version and only Post parameters)

I've tried using ClientCredentialApplicator.NetworkCredential, it didn't work. Then per the advice here, I've made my own ClientCredentialApplicator.

I still didn't work, I put breakpoints in ApplyClientCredential and they never hit.

I upgraded to the latest version (4.3.0.0), which should have this fix.

Everything works but there's no Authorization header, and the remote server answers with 301 error (which makes me think it is the same problem as the commit - the Authorization info is not added to the request until the server answers with Unauthorized and the provider I'm using answers with 301 when there's no Authorization header)

Community
  • 1
  • 1
Madd0g
  • 3,841
  • 5
  • 37
  • 59
  • Where are all the answers? – Madd0g May 21 '13 at 13:23
  • 1
    Do you get any errors? Do you have some logging in you application that prints the return codes? – Mare Infinitus May 21 '13 at 16:14
  • I see the provider returning the error in Fiddler, I know the provider requires the authorization header and that it is not being sent. No unhandled errors from the library – Madd0g May 21 '13 at 22:41
  • 1
    Are you able to tell us who the provider is? It might help to know to test possible solutions. – Andy Brown May 22 '13 at 16:14
  • https://github.com/reddit/reddit/wiki/OAuth2 - it's reddit – Madd0g May 22 '13 at 17:44
  • @Madd0g: Did you try the solution in this link:http://stackoverflow.com/questions/13623865/dotnetopenauth-clientidentifier-authorising – Saravanan May 25 '13 at 19:04
  • @saravanan - I've linked to that fix in my question - I'm using the latest version (4.3.0.0) and that fix should be there. Also - one of the answers suggests making your own `ClientCredentialApplicator`, which I did, but the breakpoint in `ApplyClientCredential` never hits – Madd0g May 25 '13 at 20:30
  • At least you're getting comments. I posted two questions recently and they both got the Tumbleweed Badge :p. – Vincent Vancalbergh Jul 15 '13 at 09:21
  • I'm not familiarized with the DotNetOpenAuth but i got a similar error in httpRequest and I solved it with a header with "PreAuthenticate" try to see if there's such a header. – Pedro.The.Kid Jul 15 '13 at 16:05
  • @Pedro.The.Kid - I think I know what you mean - authenticating on first request without waiting for an `Unauthorized` response. There's a recent patch in DotNetOpenAuth that *should* handle that. Unfortunately it doesn't work, I've opened an issue in their github, but no responses :( And yes, that's probably the problem, because the provider doesn't answer with an `Unauthorized` header, it answers with 301 and error info – Madd0g Jul 16 '13 at 05:26
  • @VincentVancalbergh - I feel for you. I think people are just afraid of these technologies. I know I was, until I tried to implement, which wasn't scary because it went pretty smoothly. Until I got to implementing support for reddit, that is – Madd0g Jul 16 '13 at 05:28
  • Check out Thinktecture.AuthorizationServer [link](https://github.com/thinktecture/Thinktecture.AuthorizationServer) – Ibraheem Jul 19 '13 at 15:15
  • I encountered the same issue. From what I remember, If you are using the HttpWebRequest C# mechanism it will only send the credentials after receiving an 401 response from the server. What you can do is add the authentication header yourself. worked for me. the link is for digest authentication so basic should be easier. link http://stackoverflow.com/questions/3109507/httpwebrequests-sends-parameterless-uri-in-authorization-header. – Omri Btian Sep 09 '13 at 07:23

3 Answers3

1

Here is the code. It works with me, when using WebClients and FtpWebRequests, e.t.c

using System.Net;

NetworkCredential credentials = new NetworkCredential("user","pass");
request.Credentials = credentials;

Hope it helps :)

Joe
  • 528
  • 5
  • 19
1

I had a similar requirement: a OAuth2 provider that requires HTTP Basic Authentication. This solution worked for me:

var authServer = new AuthorizationServerDescription { AuthorizationEndpoint = new Uri(AuthorizeUrl), TokenEndpoint = new Uri(AccessTokenUrl) };
var authClient = new WebServerClient(authServer, ConsumerKey, ConsumerSecret)
{
    ClientCredentialApplicator = ClientCredentialApplicator.NetworkCredential(ConsumerSecret)
};

There's an issue when using the DotNetOpenAuth.OAuth2.ClientCredentialApplicator.NetworkCredentialApplicator constructor which takes an instance of System.Net.NetworkCredential. The ApplyClientCredential method uses the instance ClientSecret property not the Password property from the credentials (see below).

public override void ApplyClientCredential(string clientIdentifier, HttpWebRequest request)
{
  if (clientIdentifier == null)
    return;
  if (this.credential != null)
    ErrorUtilities.VerifyHost((string.Equals(this.credential.UserName, clientIdentifier, StringComparison.Ordinal) ? 1 : 0) != 0, "Client identifiers \"{0}\" and \"{1}\" do not match.", (object) this.credential.UserName, (object) clientIdentifier);
  OAuthUtilities.ApplyHttpBasicAuth(request.Headers, clientIdentifier, this.clientSecret);
}

I know this question is old, hoping this helps someone else searching for a solution.

HOCA
  • 1,073
  • 2
  • 9
  • 20
-1

You can manually add a basic authentication header to your HttpWebRequest by accessing the request.Headers collection.

You can add the header following the indications on Wikipedia:

request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(new UTF8Encoding(false).GetBytes("username:password")));
CMerat
  • 4,398
  • 25
  • 28