简体   繁体   中英

Trouble downloading a file

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();

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);
       }

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM