4

I am trying to download a file from a C# application. I have tried two different methods, but both yield the same response: "The remote server returned an error: (401) Unauthorized."

I am pretty sure this is a credentials issue (because of the 401). If I navigate to the url from a browser, and enter the very same credentials provided, the file downloads just fine. In "Attempt 2" (below), for authtype, I have tried: NTLM, Basic, Negotiate, and Digest without any luck.

Does anyone see what I might be doing wrong here?

Thanks for the help!

Attempt 1:

string username = "username";
string password = "password";
string domain = "domain";
string url = @"http://LiveLinkInstance.com/livelink/llisapi.dll/999999/WordDocument.docx?func=doc.Fetch&nodeid=999999&ReadOnly=True&VerNum=-2&nexturl=/livelink/llisapi.dll?func=ll&objId=888888&objAction=browse&viewType=1";  

// Create an instance of WebClient
WebClient client = new WebClient();
client.Proxy = null;

client.Credentials = new System.Net.NetworkCredential(username, password, domain);

client.DownloadFile(new Uri(url), @"C:\FileDownloads\test.txt");

Attempt 2:

string username = "username";
string password = "password";
string domain = "domain";
string url = @"http://LiveLinkInstance.com/livelink/llisapi.dll/999999/WordDocument.docx?func=doc.Fetch&nodeid=999999&ReadOnly=True&VerNum=-2&nexturl=/livelink/llisapi.dll?func=ll&objId=888888&objAction=browse&viewType=1";

HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);

string credentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(domain + "\\" + username + ":" + password));
wr.Headers.Add("Authorization", "Basic " + credentials);

CredentialCache cc = new CredentialCache();
cc.Add(new Uri(url), "NTLM", new NetworkCredential(username, password, domain));
wr.Credentials = cc;
Stream str = ws.GetResponseStream();
svick
  • 236,525
  • 50
  • 385
  • 514
RepDetec
  • 741
  • 13
  • 29
  • In attempt #2 the manual setting of the header seems redundant (even conflicting) with the use of CredentialCache. Then try and guess the settings (with/without domain, Basic/Digest/etcc). Or, better yet, try using something like Fiddler or Httpwatch to understand what is the authentication scheme used in the browser. – Amitay Dobo Sep 14 '10 at 01:59
  • Amitay, thanks. I actually tried it with and without that. I agree. It is totally redundant. I think fiddler is a great idea. I'll give it a shot. – RepDetec Sep 14 '10 at 02:26

3 Answers3

1

Did you try

client.UseDefaultCredentials = true 

if you are using MVC or WebApi you should decorate your method with

[Authorize]

If you are able to impersonate a user, use it like this

 WindowsIdentity wi = null;
 wi = (WindowsIdentity)HttpContext.Current.User.Identity;

 using (wi.Impersonate())
       {
         var client = new WebClient { UseDefaultCredentials = true };

         client.Headers.Add(HttpRequestHeader.ContentType, "application/json; charset=utf-8");
            var result = JsonConvert.DeserializeObject<Object>(Encoding.UTF8.GetString(client.DownloadData("http://api.com/api/values")));

         return Request.CreateResponse(result);
       }
BrunoMartinsPro
  • 1,646
  • 1
  • 24
  • 48
1

As Amitay said, using fiddler to compare against traffic from browser is the best way to go. BTW, look here on SO - what's happening is OP's case was that request was getting redirected to different location but credentials were not re-passed. So OP did manual redirection to solve the issue.

Community
  • 1
  • 1
VinayC
  • 47,395
  • 5
  • 59
  • 72
0

I saw LL using its own form-based authentication or SSO based on IWA. I don't know if you can use other HTTP authentication types.

If your server uses the (default) form authentication you would have to use LAPI or WS to download the document providig the LL credentials within the LAPI/WS call. You could also just get a cookie for HTTP communication by LAPI/WS.

If you have SSO configured you can set Credentials to CredentialCache.DefaultCredentials to pass in credentials of the currently authentified Windows session.

Ferdinand Prantl
  • 5,281
  • 34
  • 35