0

I'm trying to use an outside REST api that was recently developed by an outside company. They provided me with some Java code to show how to connect to it and retrieve data, but so far I'm having no luck getting any results with C# MVC 4. Currently I cannot even login to the system. The credentials are correct, and using examples that I've found elsewhere don't seem to help.

The Java code that works:

try{
  ClientConfig client_config = new ClientConfig();
  client_config.register(new HttpBasicAuthFilter(username,password));

  Client client = ClientBuilder.newClient(client_config);
  WebTarget web_target = client.target(url);
  Invocation.Builder invocation_builder = web_target.request();

  //This GET does the login with basic auth
  this.populateFromResponse(invocation_builder.get());
}
catch(final Exception e){
  System.out.println(e.toString());
}

Ok, there are objects here that I don't have in C#, clearly, but everything I've tried has yet to work.

I have tried placing info in the header of the request:

request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));

No cookies, also tried:

request.Credentials = new NetworkCredential(username, password);

Nothing. If I try this, receive no cookies, and still attempt to access any other part of the api, then I get a 401(Not Authorized) error. The request.GetResponse(); doesn't throw an error if I'm simply trying to access the login section of the api.

I'm new to REST services, so any help/direction is appreciated. I'm only asking because everything else that I've looked up doesn't seem to work.

Edit Here's how I'm building the request:

var request = (HttpWebRequest)WebRequest.Create(HostUrl + path);
request.Method = "GET";
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password));
var response = request.GetResponse() as HttpWebResponse;

Edit #2 Thanks to @BrianP for his answer, which led me to solving this issue a little better. Below is my current code (along with additions to collect cookies from the response taken from this question) that finally returned a success code:

var cookies = new CookieContainer();
var handler = new HttpClientHandler();
handler.CookieContainer = cookies;

var client = new HttpClient(handler);
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(username + ":" + password)));
client.BaseAddress = new Uri(HostUrl);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var response = client.GetAsync(HostUrl + "/api/login/").Result;
var responseCookies = cookies.GetCookies(new Uri(HostUrl)).Cast<Cookie>()

Please let me know if there are improvements for this code. Thanks again!

Community
  • 1
  • 1
Dredj
  • 137
  • 1
  • 2
  • 10
  • Have you tried using something like Fiddler to capture a working trace from the Java code and a non-working one from yours to see the difference? Also - what is `request` in your code? Can you show a more complete example? – Brian Reischl Dec 12 '13 at 17:25
  • @BrianReischl Posted more code. I'll take a look with fiddler and see what I may be missing. – Dredj Dec 12 '13 at 17:39
  • Looks like either of your attempts should work, assuming a correct username & password. Hopefully Fiddler will provide some more information. – Brian Reischl Dec 12 '13 at 17:44
  • Are you sure it's using basic auth, and not a custom Forms-based auth? – Jerod Venema Dec 12 '13 at 17:45
  • @jvenema The devs of the api have told me it's basic auth. I have a username/pass that they provided to log into their api and access it. – Dredj Dec 12 '13 at 18:01

1 Answers1

0
public void SetBasicAuthHeader(WebRequest req, String userName, String userPassword)
{
    string authInfo = userName + ":" + userPassword;
    authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
    req.Headers["Authorization"] = "Basic " + authInfo;
}

Pulled from: http://blog.kowalczyk.info/article/at3/Forcing-basic-http-authentication-for-HttpWebReq.html

EDIT: Based on Comments.

HttpRequestMessage requestMsg = new HttpRequestMessage();
string data = username + ":" + password;
requestMsg.Headers.Authorization = new AuthenticationHeaderValue("Basic", data);
Brian P
  • 1,569
  • 13
  • 23
  • This is basically what I'm already doing (see edit), but it doesn't appear to be working. – Dredj Dec 12 '13 at 17:44
  • Encoding type makes a difference. What is the encoding of the request vs. you are explicitly setting ASCII... – Brian P Dec 12 '13 at 17:45
  • I've tried both ways. It doesn't appear to make a difference so far. The credentials are correct, I'm certain of that. – Dredj Dec 12 '13 at 18:02
  • What version of .Net are you running? – Brian P Dec 12 '13 at 18:24
  • @BrianP I'm running .NET 4.5. – Dredj Dec 12 '13 at 18:27
  • 1
    Ah ha! New to .Net 4.5 http://msdn.microsoft.com/en-us/library/hh137974(v=vs.110).aspx They updated it, likely because it was difficult to work with. Disclaimer: I have used this in a home grown OAuth and I am assuming it also works with Basic. See post for edit. – Brian P Dec 12 '13 at 18:37
  • 1
    @BrianP This got me on the right track. I starting looking up this new object and realized it needed different objects and set up altogether. After putting it together I ended up with a success response along with the cookies I expected. I'll add the changed to my post and mark your answer. Thanks! – Dredj Dec 12 '13 at 19:57